在学习权限之前,先学习shell命令及运行原理。
我们所说的操作系统是指Linux内核,也就是kernel。但是用户是不直接使用kernel的,而是使用"外壳"程序,也就是shell,来操作kernel。
这样做的具体原因先来简单认识一下:
完成kernel的操作,需要三方共同进行:用户——提出需求,shell外壳——接受需求,返回结果,kernel——处理需求。
使用shell外壳的原因之一就是直接使用kernel很难操作。
shell的最简单定义就是命令行解释器。
作用是将使用者的命令翻译给核心(kernel)处理,再将核心的处理结果翻译给使用者。
Linux下的外壳就是命令行解释器,而Windows下的外壳就是图形化界面。外壳存在的直接意义是降低操作OS的成本。
外壳程序的另一个意义是保护操作系统。比如Linux服务器的普通用户想要做一些root用户才能做的事,这时候外壳程序直接拦截请求,不会再交给kernel处理。还有在输入错误指令的时候,也会直接拦截。
shell是外壳程序,是命令行解释器的统称,涉及到具体的命令行解释器,比如我们所使用的centos 7的命令行解释器叫bash。
bash是user/bin目录下的可执行程序。
Linux权限
Linux中具体的用户分类:root用户,普通用户。和Windows下的管理员用户,普通用户一样。
普通用户的权限是受管控的。而root用户可以在Linux下做任何事情。
普通用户的命令行提示符是$,而root用户的命令行提示符是#。
命令:su [用户名]
作用:切换用户。
一般使用su - 指令。使用su - 指令后,会要求输入密码,这里的密码输入是不回显(回显示器,即不显现)的。然后输入要切换用户的密码。应该没有人把两个账户的密码设置成相同的吧?如果有,最好改掉。使用su - 指令登录root用户后,如果想要返回普通用户,热键Ctrl +d就能回到普通用户。(su - 指令能不能切换任意用户存疑)
关于root权限的了解,比如有三个用户:甲,乙,root。你自己有root账户和账户甲的密码,现在想要登录账户乙,只需要切换到root账户,然后su [乙的用户名]就能直接切换到乙的用户。而且进行指令操作的时候是以乙的身份被记录到历史中的。
所以root账户的密码越复杂越好。
Linux下的文件权限
第一个框中的内容称为文件属性,第二个框中的内容称为文件内容。
要学习文件权限,首先要理解的是文件属性中第一组的字母所代表的含义。
第一组字母由十个字符组成。第一个字符都是-,创建一个目录文件看看。
目录文件的开头是d。
想这样的第一组第一个字符称为文件类型。
Linux 系统不是通过文件名后缀来区分文件类型的,而是通过 ls - l 显示的第一个字符来区分文件类型的。把a.out改为a.txt不会影响程序的执行。
-:普通文件,包括文本,源代码,可执行程序,第三方动静态库等,不像Windows下的普通文件就是文本文件。
d: 目录文件
l : 链接文件(Windows下的快捷方式就是一种链接文件)
p: 管道文件
b: 块设备文件,典型的:磁盘
c:字符设备文件,即终端,比如物理终端显示器,虚拟终端xshell
以上就是Linux下常见的文件名。目前只需要记住:- 和 d。
先看看各个文件的样子:
管道文件
具体作用可以登录两个账户(账户相同,点击窗口旁边的+符号),在一个用户下输入:echo "待输入内容" > pipe,此时命令行卡住;另一个账户进入pipe所在路径,输入:cat < pipe,结果打印出待输入内容,并且命令行卡住的账户,命令行正常显现。
链接文件
字符设备文件:要到一些目录下找。
块设备文件:数据库的时候会讲到。
通过ll指令查看第一个字符只能简单的查看文件类型,如果需要更详细的信息可以通过file [文件名]来完成。
既然Linux不是通过文件名后缀来区分文件的,那是不是意味着可以使用gcc编译器来编译任意后缀的文件了?先试试看。
结果已经出来了,文件格式不被接受。
原因也很简单,gcc并不等同于Linux,gcc只是一个编译器软件,Linux不通过后缀区分文件,不代表gcc不通过后缀区分文件。这是特定的Linux软件的需求,而不是Linux的需求。
Linux权限管理
第一个问题:什么是权限?
用我自己的话来说是:权限是人对事物所具备属性的使用权力,不同的人对同一件事物具有不同的权限。
比如餐厅,餐厅具备提供食物,加工食材的属性,其中消费者具有获取食物的权限,但不具备加工食材的权限,而店员具备获取食物,加工食材的权限。餐厅不具备提供按摩的属性,即使是餐厅的最高权限者,也不具备按摩的权限。
所以我们学习的Linux权限,是对文件的权限。
权限分为两个方面:
1.这个文件谁能“访问”,谁不能“访问”。访问即读,写,执行
2.文件所具备的属性,要对文件行使某种权力,文件首先得具备对应的属性。
权限 = 人 + 事物属性
所以权限的概念及操作,都是围绕着人和文件属性来展开的。
Linux系统中,人分三类:
1.文件的拥有者,owner
2.文件的所属组,group
3.文件的其他用户,other
这三类属于角色,而root用户和普通用户是具体的人,两者并不冲突。root可以是拥有者,所属组,其他用户,普通用户也可以是拥有者,所属组,其他用户。
关于所属组,要用具体实例来说明:现在公司有一台开发机(也就是服务器),对于员工,不同的老总态度不一样,有的认为多组人员开发同一组项目是对人力资源的浪费,有的认为多组员工开发同一个项目能提高项目的竞争能力。现在假设是多组人员开发同一个项目的情况,存在项目组A组,项目组B组两组人员。A组的张三和B组的李四分别创建了项目目录:groupAdir,groupBdir。A组和B组是竞争关系,A组的张三不想B组的人看到自己写的代码,且要保证A组的成员能看到自己的代码。如果分成两类,就是除了拥有者,都是其他用户,拒绝了李四的访问,也拒绝了其他人的访问。所以诞生了新的角色:所属组。那么就可以将项目目录的拥有者设为张三,所属组设为A组,其他用户设为除A组外的所有人。(对应角色的权限是可以设置的)
Linux系统中,文件的权限属性分三类
1.r——读read
2.w——写write
3.x——可执行execute
蓝色框中的信息代表什么人对文件具有什么权限,白色框中的是文件的所有者,红色框中的是文件的所属组(现在所属组是默认状态),如果既不是拥有者,也不是所属组,那就是other。蓝色框内第一列是文件的类型,剩下的三三为一组,第一组为拥有者的权限,第二组为所属组的权限,第三组为其他用户的权限。以第一组为列,每一组,对应权限的位置含义是确定的,第一个位置只能是r或者-,第二个位置只能是w或者-,第三个位置只能是x或者-。三个位置代表是否具有某种权限,没有就显示-,有就显示对应字母。
以file.txt文件为例,file.txt是一个普通文件,拥有者具有读写的能力,所属组具有读写的能力,其他用户只具有读的能力。
文件的权限操作,具体涉及那些方面?
1.修改文件的属性
2.修改人
具体来说就是修改某些人对文件属性的权限。
file.txt没有执行权限,有读写权限
修改权限的指令:chmod u-r file.txt
这条指令的含义是:消去file.txt拥有者的读权限。
指令含义:
chmod:change mode
u:user,即拥有者;g:group,即所属组;o:other,即其他用户
-:消去;+:增加
r:读权限;w:写权限;x:执行权限
加上执行权限,不代表就能执行了
给所有人加上所有权限:
给所以人去掉所有权限:
当不具备某种权限时,进行权限使用时,会被拒绝。
那么root账户进行这些操作会有什么结果呢?
root即不是拥有者,也不是所属组,所以属于其他用户,在其他用户没有权限的情况下,root账户想写就写,想读就读,root账户不受约束。包括文件的拥有者是root,然后把拥有者的权限全去掉,root依然可读可写。权限约束的是普通用户,root不受约束。
人的权限,有,会存在对应字母,没有,会显示 - ,这是一个两态的模式,和二进制很像。比如rwx代表111,对应的八进制数为7,可以说权限为7;假设owner的权限为5,八进制转换为二进制为101,对应r-x,即owner拥有的权限为r-x。这是一个人的情况,三个人的权限,可以用三个八进制数来表达,利用这点可以进行一个更方便的权限修改方式。
简单来说就是按八进制进行操作,按二进制来理解。
还有一种修改方式:chmod a = r file.txt
a即all,a = r会将权限改为-r--r--r--,a = rw会将权限改成-rw-rw-rw-
如何修改文件的拥有者?
指令:chown [要修改成的拥有者] [文件名]
像这样直接修改会报错。很简单的一个道理:当你给别人东西的时候,要不要进过别人的同意?
在系统中如何证明经过别人的同意了?
在前面加上sudo:sudo chown [要修改成的拥有者] [文件名]
然后输入本账户密码就行了。
这里的sudo是短暂提升权限(提升到root权限)的意思,Linux中经过对方同意不一定真的要对方同意,还可以让一个更高权限的人来强迫对方同意。sudo指令需要信任列表相关知识,现在还没有办法sudo。
第一次sudo需要密码认证,以及时间完成认证,之后就不需要认证了。
还有一种修改方式:切换成root账户,直接改。
修改文件的所属组:chgrp [要修改成的所属组] [文件名],机制和修改拥有者一样。
也可以一条命令修改拥有者和所属组:sudo chown [要修改成的拥有者]:[要修改成的所属组] [文件名]
当然修改了文件的拥有者并不意味这拥有者就一定能使用文件,因为文件所在目录也具有权限性质。正常来说是可以的,但是如果修改目录权限,那么文件的拥有者也不一定能使用文件。
下面来了解一下目录的权限。
要进入一个目录需要什么权限?
需要x权限。验证方式:chmod依次去掉rwx,看还能不能进入目录。
如果仅没有r权限,那么允许在目录下创建(写入)文件,允许进入目录,但是不能看目录内的内容。
如果仅没有w权限,那么允许查看目录文件,允许进入目录,但是不能在目录下创建文件。因为创建文件要把文件名放到目录下,其实就是对文件内容的修改。
如果同时没有rw权限,仅有x权限,允许进入,但是不允许查看和创建目录下的文件列表。(不是文件内容,文件内容是否可查看,由文件的权限决定)
虽然这么说了,但是又有一个很矛盾的点:文件是通过路径访问的,要使用路径,目录就必须具有读取文件的权限,因为要找到文件是要读取目录文件的内容的,而只记住文件名是没什么用,文件是有文件编号的,要找到一个文件的内容,通常是通过文件名找到对应的文件编号来完成操作的,这些都需要目录的读权限。在目录的读权限被去除后,应该是不允许访问目录内文件内容的。但还是成功访问了,原因可能是文件和id的映射关系被系统缓存了。
Linux下一切皆文件,目录也是文件,文件=属性+内容,目录的内容是目录下部分文件的"属性"(说是属性并不准确),包括文件名。要想讲透,还需要后面的知识。
问题:什么创建目录的默认权限是775,创建普通文件的默认权限是664?(不同的系统之间可能有差异)
创建目录文件的起始权限为777,创建普通文件的起始权限为666;系统中存在一个系统掩码:
第一个0表示:这是一个八进制数
权限掩码的意义:凡是在权限掩码中出现的权限,都不应该在最终的权限中出现。起始权限到最终权限不是减去权限掩码的数,而是通过其他方法来确定,示例:
777:111 111 111
002:000 000 010
775:111 111 101
要想验证是不是减去权限掩码的数,就要修改权限掩码,当权限掩码为002的时候,怎么计算都是符合减法规则的。
修改权限掩码的命令:umask [要修改成的权限掩码]
当把权限掩码改为000时,创建目录文件后,发现权限变成了777,说明文件的最终权限确实会受到权限掩码的影响。
由图可知,在修改权限掩码为003后,创建普通文件的权限仍然为664。如果是减法:
666:110 110 110
003:000 000 011
文件的权限应该是663,但实际上是664。所以权限掩码对文件最终权限的影响机制不是减法。
权限掩码影响文件最终权限的机制:权限掩码取反,然后和文件初始权限进行按位与运算,得出的结果就是文件的最终权限。
~003:111 111 100
666: 110 110 110
结果: 110 110 100
公式:最终权限 = 默认权限 & (~权限掩码)
权限掩码存在的意义:方便用户在某些时候创建一批特定权限的文件。
粘滞位
有时候会需要各种人在某个目录下创建或删除临时文件的情况。系统当中也存在保存临时文件的目录。
根目录下有一个tmp目录,拥有者和所属组都是root,除root以外的用户都是other,但是other在tmp目录下是有读写权限的。也就是说这个目录是给普通用户存放临时文件用的。
当然不代表一定要将临时文件存放在tmp目录下,也可以放在自己创建的目录下,但是存在和其他项目协作的情况,这时候tmp目录的作用就显示出来了,简单来说就是:可以不用,但不能没有。
切换到root账户,在文件夹中创建一个目录,将目录权限改为777达到模拟临时目录的效果。
切换回普通用户,进入那个目录。
虽然all的拥有者和所属组都是root,但是other也可以进入,可用读,可以写。也就是说,所有人都可以在这个目录下创建删除文件(不考虑上级目录中存在限制的情况)。
在这个目录下,文件的拥有者可以对文件的权限进行修改,也就是说,如果不想让其他人看见和修改文件内容,可以把权限改成660,但是每个人都有all目录的写权限,也就是说,别人虽然读不了文件,但是可以删除文件。从逻辑角度,这是一个不合理的行为。这时候,粘滞位的作用就显现了出来。可以让除文件拥有者以外的人无法删除文件。粘滞位是加在共享目录上的(由root加)。
命令chmod +t [目录文件]就是加上粘滞位的指令,加上后发现,other的权限变成了rwt,t就是粘滞位。除文件拥有者以外的人就没法删除文件了(root还是能删的,目录的所有者也可以删)。
再回头看系统中的临时目录文件/tmp,发现,tmp的other权限也是rwt。说明tmp是加了粘滞位的。