一、用户问题
Linux系统中用户可以划分为两类:
- root用户
- 普通用户
因为Linux是一款多用户操作系统,它可以同时允许多个不同的用户同时登陆和使用的系统,而且多用户在原则上是相互隔离、互不影响的。这里的多个用户指的就是普通用户,而root用户被称为超级管理员。
对应的,在Windows系统中,有管理员(Administrator)和普通用户。我们用鼠标右键打开一个软件时通常会有一个选项就是"以管理员身份运行"。
在Linux中,root用户和普通用户的区别就是,root用户权限高,普通用户权限低。权限低就说明他会受到管控,也就是有些事他是不能做的。普通用户一般是在/home目录下,超级用户一般是在/root目录下,超级用户的命令提示符是"#",普通用户的命令提示符是"$"。
当然,我们可以通过命令来实现从普通用户转变为超级用户,也可以通过命令从超级用户转变为普通用户。
1、普通用户->超级用户
(1)命令一:su
使用su命令(仅仅一个su,后面没有东西)后,需要我们输入超级用户的密码才可以转变成功。转变为超级用户后,我们的权限就变大了,可以执行的操作就变多了。用su命令切换时,相对应的工作目录不会改变,也就是说如果我们是普通用户且当前工作目录为/home/usr1/xxx,那么用su命令切换后,此时的工作目录还是/home/usr1/xxx,但是权限被放大了。我们可以将su命令理解为只是给当前用户换了一种身份,当前用户是没有改变的,就比如我们在冬天不穿衣服,我们会感到冷,如果穿上衣服(权限增大),那么就会舒服许多,但我们还是我们,我们本身并没有发生变化。
如果此时想退回普通用户(脱掉衣服,权限缩小),可以用exit命令,也可以Ctrl+D快速退回。
(2)命令二:su -
su -也可以用来切换身份。后面如果什么都没有,就代表着切换到超级用户。su -的意思就是让我们以root用户的身份重新登陆了,重新登陆就意味着我们的工作目录就到root的家目录下了(/root)下面了,所处的工作目录发生变化了。
su -我们就可以理解为我们在冬天不穿衣服,我们会感到冷,结果执行完su -后,来了一个穿着羽绒服的人取代了我们,此时的我就没有了。
如果此时想退回普通用户(把我喊回来,然后自己走掉,权限缩小),可以用exit命令,也可以Ctrl+D快速退回。
2、超级用户->普通用户
现在想让超级用户变为普通用户(注意,不是退回普通用户)。
(1)命令一:su 普通用户
su后面直接跟普通用户的名称,前提是确保这个用户存在(可以通过ls /home进行查看),执行这条命令后不需要我们输密码。
如果此时想退回超级用户,可以用exit命令,也可以Ctrl+D快速退回。
(2)命令二:su - 普通用户
同样的,执行后也不需要我们输入密码。它与su的区别,就和普通用户转超级用户时,su -与su的区别一样,这里就不重复了。
如果此时想退回超级用户,可以用exit命令,也可以Ctrl+D快速退回。
总结:
如果两个用户想要互相转换,那么可以用su和su -命令,它们两个的区别想必大家已经清楚。假设有两个用户分别是user1和user2,分为以下几种情况:
1、use1是超级用户,user2是普通用户
user1->user2:su user2 / su - user2 不需要输密码
2、user1是普通用户,user2是超级用户
user1->user2:su / su - 需要输入超级用户的密码
3、user1是普通用户,user2是普通用户
user1->user2:su user2 / su - user2 需要输入user2的密码
大家搞清楚su和su -的区别基本上就没什么问题,不要刻意去背。
二、sudo指令
sudo是用来对指令进行短暂提权的。一些情况下,由于普通用户的权限较小,所以可能不能成功执行某条指令,所以就需要短暂提权来帮助我们普通用户暂时获得更高的权限。
比如说,安装软件,安装软件的本质就是将该软件(文件)拷贝放到/usr/bin这个目录下。对于普通用户来说,他是没有能力将一个文件拷贝放到/usr/bin这个目录下的,因为这个目录是属于root用户的,而不是属于普通用户的(下面会讲到文件的所属关系),所以这时我们就可以用sudo指令来进行短暂提权,提权后,我们普通用户就可以安装所需要的软件了以及一些其它操作。
我们第一次使用sudo时需要输入当前用户的密码,这个密码会维持10-15分钟,在这段时间内我们用sudo命令就不需要输密码了,这段时间过后,用sudo命令就还需输入密码。
大家这时肯定会有疑惑,既然sudo可以提权,那超级用户存在的意义是什么?
实则不然,并不是每个普通用户都可以执行sudo命令的:
如果普通用户想要执行sudo,就必须将该用户放到/etc/sudoers这个配置文件中(具体怎么放,我们在下篇讲到vim这个编辑器后再谈),初学者如果想要提权,可以暂时用su命令来代替sudo命令。
三、权限问题
什么是权限?
权限的本质就是:能或者不能做什么事情。比如,校长可以进校长的办公室,而普通学生是不能进的,再比如,一些视频只有VIP能看,其它非VIP的不能看,这些都是权限问题。
为什么要有权限?
为了控制用户的行为,防止错误的发生。
比如:一台机器上有多个用户,如果没有权限问题,用户1写的内容可能很快就被用户2给拿走或者修改,那么这就可能会出现各种各样的麻烦。
如何理解权限?
权限首先限制的是"角色"。 --- 校长能进校长办公室,而普通学生不能进校长办公室,限制的是普通学生(人),假设校长名为"张三";校长能进办公室是因为他叫"张三"?还是因为他的身份是校长?显而易见,肯定是由于他的身份是校长,所以,在这个世界上,你是谁并不重要,你扮演什么样的角色非常重要!我国的法律也是如此,法律是在各种角色之间形成起来的,它不是针对具体的人。我们看视频时,有些电视剧或者电影需要VIP,你能看,不是因为你这个人,而是因为你是VIP。
权限要求目标必须具备对应的属性。如果你要访问的目标对象天然没有目标属性,那么你也绝对不会具备相应的属性权限。--- 比如你不可能在leetcode上看电影吧?你也不能在爱奇艺上敲代码吧?也就是说,你要访问的爱奇艺本身就不具备写代码的功能,那么任何人都不可能有权限去在爱奇艺上写代码。再比如说,我今天要访问一个文件,而这个文件天然的对任何人都没有"写"属性,那么任何人过来,这个文件都不让写入,所以文件本身不具备"写"属性,那么我们任何人也就不会具备"写"权限。
所以,权限 = 角色 + 目标权限属性。
1、角色
在Linux角色分为3种:
1、拥有者
2、所属组
3、other
我们当前的用户是blue,也就是普通用户,一个系统未来可能有多个用户,这些用户和拥有者、所属组、other的关系就如同上面我们所说的张三和校长的关系。**拥有者、所属组、other充当的是角色,我们的用户代表的只是名字(具体的人)**。角色必须由具体的人来扮演,所以blue这个人,既可以是拥有者,也同时可以是所属组,或者other,这3个角色不但不冲突,而且是相互补充的!
ll查看文件属性时,为什么没有看到other?
other信息并不需要记录下来,我们查看文件属性时,如果不是该文件的拥有者或者是所属组,那么就是other。对于一个文件来说,other可能会有许多,没法记录,也不需要记录。
拥有者就表示该文件是由哪个用户所创建的,那么该用户就是该文件的拥有者。
什么是所属组?为什么有所属组?
所属组可以是许多用户构成的一个组(以其中一个用户命名,其它用户添加到这个组中),当然,也可以自成一组(常见)。
假设在XXX公司有两个组,分别是A组、B组,现公司想要开发一款软件,为了让这款软件做出来时更好,于是决定采用"赛马"制度,大致内容就是给一个相同的任务让两个团队都研发,结果认可度高的那个团队公司会优先推广它们的产品,于是A,B两个组开始做了,A、B两组都有10个成员,一天,A组的组长想要看看组内成员1的代码内容,如果没有所属组,那么成员1所写的文件只属于他自己,要想被组长看到,就需要放开other权限,一旦放开other权限,B组所有人都可以看到,那么就可能会出现"抄袭"的现象。设计者肯定是想到了这一点,于是设计出所属组这一角色。所以A组组长就可以将它的10个成员都放在同一个所属组中,A组成员1只需将所属组的权限打开并关闭other权限,那么A组其他成员就可以通过所属组看到成员1所写的内容,但是B组任何人就看不到了。
所属组的存在是为了更精细化的权限管理,更精细化的身份角色才能进行更近细化的权限管理。
2、目标权限属性
在Linux中一切皆文件,所以我们面对的都是文件(目标)。对于文件来讲,它天然一定要具备的与权限相关的文件属性有:读、写、执行。
我们描述一个文件的权限时应该是这样的:xxx文件的拥有者具备xxx权限、所属组具备xxx权限,other具备xxx权限。
具体的每个角色所具备的权限可以这样看:
一组中从左到右依次是读权限、写权限、执行权限(顺序是固定的)。r代表有读权限、w代表有写权限、x代表有执行权限,如果该位置上是-,那就代表没有相对应权限。每一组中的第一个字符只能是r或-,第二个字符只能是w或-,第三个字符只能是x或-。
以上图为例,f1.txt的拥有者具备读写权限(能对该文件进行读或写),但不具备执行权限(不能运行该文件);所属组具备读写权限,但不具备执行权限;other具备读权限,但不具备写、执行权限。
四、操作权限
操作权限的本质就是修改文件权限,修改文件权限本质就是修改文件角色或文件权限属性。
1、修改文件权限属性
(1)chmod指令
用户符号:
- u表示拥有者
- g表示所属组
- o表示其他用户
- a表示所有用户
通过上面的学习,其实还有一种方式也能修改文件权限属性:
我用黄色矩形圈起来的那部分中每个位置上的字符只有两种情况,要是对应的权限(r/w/x),要么是-,所以其具有"二态",那么我们就可以用0/1来表示,如果是1就表示对应权限存在(r/w/x),如果是0就表示不存在,所以我们就可以转换为"111 000 000"。因为这样写不好看,所以我们写成8进制的表示形式,由于最高就是111,所以用8进制表示完全够用,所以可以写为"700",其中7转换为2进制就是111,说明该文件的拥有者对该文件具有读写执行权限...。所以我们就可以通过这一方式来修改文件权限:
现有一个问题,当前用户能改其它任何人的文件权限吗?
所以,用户只能更改自己的文件权限。如果非要改其他人的文件权限,那就用sudo来短暂提权或者变为root用户。
这里又有一个问题,如果文件没有权限怎么办?
所以,对于一个目标文件来讲,如果我们本身不具备某种权限,那么系统就会拒绝让我们访问。
还需要注意一点的是,确定权限信息的时候,系统会先确定用户是谁,到底是该文件的拥有者?所属组?还是other?
在CentOs下,用户角色只确定一次,顺序是:拥有者,所属组,other。通俗理解,如果你是该文件的拥有者,那么你在该文件中扮演的角色只能是拥有者。比如:
特别的,对于root用户,即使一个文件的拥有者和所属组都不是root,且将该文件other用户的读写执行权限全部关闭,那么root用户也可以对该文件进行读写执行。root是超级管理员,他不会受到任何权限约束,他甚至可以将你写的文件的拥有者和所属组全部改为root!
所有的权限、规则都是用来限制普通人的。
如何理解可执行权限?
我们对f1.txt拥有者加上了可执行权限,但是当我们执行该文件时却发现不能执行!
我们这里需要理解的是:可执行权限 != 文件可以执行
"给你机会,可你不中用啊"这一句话就可以解释上面的问题:给了你一个机会,但你自身能力不能这么做。现在****给你可执行的权限,只是允许这个文件将来可以被执行,但是这个文件本身就不能执行,你要执行,就会出错!
也就可以理解为:这个文件要想被执行,首先,它自身是可执行程序,其次,执行者对该文件必须有可执行权限。
可执行程序(Executable Program)是一种计算机文件,它包含了可以直接由计算机的操作系统加载并执行的机器码(二进制)。程序通常是在编译或解释源代码之后产生的,源代码是程序员使用某种编程语言编写的指令集合。
2、修改角色
修改角色本质上就是修改一个文件的拥有者和所属组。
(1)chown
chown指令用于更改文件的拥有者。
在执行"chown root f1.txt"时,失败了,为什么系统不让我的文件给别人?
道理很简单,如果你在程序中写一个bug然后将这个文件给别人了,那甩锅和接锅的人就都来了,显然你是甩锅者,别人就是接锅者,那还怎么玩?你今天传一个bug过去,明天再传一个bug...时间不需要太久,马上你们俩就要打起来。
所以,系统默认不允许我们把文件给别人,这也是合理了!也就是说你将文件给别人前需要经过别人同意;也就是说你要将文件给别人,每次都需要跑到人家身边问问是否同意,这不是有点扯嘛?所以我们要想将文件给别人,必须要有高权限!!!,高权限就意味着,即使你不想要,也必须要(就是这么霸道)!
要想获得高权限,就可以用sudo/su命令:
使用chown也可以同时修改拥有者和所属组:
(2)chgrp
chgrp指令用于更改文件的所属组。
使用chgrp指令也需要高权限:
chgrp只修改所属组。chown可以只改拥有者,也可以将拥有者和所属组同时修改。
我们可以用chown代替chgrp,如果只想修改所属组,那么可以用chgrp。
五、其它
1、理解目录权限
如果我们是目录的拥有者,那我们进入该目录需要有什么权限呢?
很多同学起初会认为需要有读权限,那我们来验证以下:
不难看出,我们进入该目录并不需要读权限,那么需要写权限吗?
显然,也不需要写权限。 所以,进入一个目录需要有相对应的执行权限:
那么r和w对于目录文件意味着什么?
(1)对于r
如果没有r权限则不能查看该目录下的内容。
(2)对于w
如果没有w权限则不能在该目录下创建新的文件。
总结:
1、进入目录需要x权限
2、查看目录内容需要r权限
3、在目录中新建文件需要w权限
当然,如果是超级用户(root),那就可以"为所欲为"了,超级用户不受权限约束。
默认情况下,新建一个目录,该目录会对拥有者开放读写执行权限。
2、理解Linux多用户之间相互"隔离"
在Linux系统中,每新建一个普通账号就会在/home目录下新建一个以特定用户名命名的文件夹,每一个文件夹都表示不同的用户,我们登陆账号时就会进入自己家目录中(也就是/home目录下的自己的账号文件夹中)。
从上图中,可以看出blue这个文件夹的拥有者和所属组都是blue,而这个目录只开放了拥有者对该目录的读写执行权限,这意味着,任何其它普通用户都无法进入blue用户的家目录!这就形成了用户间"隔离"的状态。
总结:任何普通用户,都无法进入其它用户的家目录!用户与用户之间相互"隔离",互不影响。
3、缺省权限
为什么新建一个普通文件和新建一个目录,它们的文件权限是不一样的?
对于普通文件来讲,它的起始权限通常是666,默认不带可执行权限。
对于目录文件来讲,它的起始权限通常是777,默认带可执行权限。
可是,从上图中我们看到新建一个普通文件的权限是:664,新建一个目录文件的权限是775,这与666和777不符啊,这是为什么呢?
这是因为,在Linux系统中,有一个叫做权限掩码(权限屏蔽字)的概念,我们可以用umask指令查看:
我们只需考虑后面3个数字---002,002是一个八进制数字,它转换为二进制是000 000 010,这一串二进制就是权限掩码,我们新建一个文件实际看到的权限应该遵循:
最终权限 = 起始权限 & (~umask)
以上述为例(umask = 002):
对于普通文件:起始权限666,也就是110110110,umask为000000010,umask为111111101,最终权限 = 起始权限 & (umask),故最终权限 = 110110110 & 111111101 = 110110100 = 664
对于目录文件:起始权限777,也就是111111111,umask为000000010,umask为111111101,最终权限 = 起始权限 & (umask),故最终权限 = 111111111 & 111111101 = 111111101 = 775
如果我们新建的文件和目录的权限起始值不是664和775,那么就是我们的umask中后三位八进制数字不一样。
了解完上面的内容后,相信大家会有一些问题:
1、umask存在的目的是什么?
通过上面的计算规则中我们可以看到:凡是在umask中出现的权限,都不会在最终权限中出现。
例如,umask=002,它表示不管你创建什么文件,你的文件初始权限中都不允许other去进行w操作。
我们通过umask的值就可以控制新建文件时的初始权限!
2、umask存在的意义是什么?
如果没有umask,那么我们在新建文件时的默认权限就是由系统决定,无论什么时候创建新文件,它的权限一直保持不变(也就是系统将默认权限写"死"了),也就无法在创建前改变权限。如果一些用户就想创建出来的文件的权限是他自己想的那样,若没有umask,就做不到;如果有umask,用户就可以在新建文件前根据自己的意愿修改umask的值,然后创建文件,这时用户就不必单独去修改文件权限了。
特殊情况下,配置umask可以控制文件的默认权限,让我们的代码都是可控的。比如说,今天你在你的系统上创建一个文件,可以读写,然后你写了一段c语言代码放进去。接着,你换成另外一个系统,这个系统中的umask直接将读写权限禁掉了,这时你创建了一个文件,进行去读,发现根本读不到任何内容,这时就会出现问题。
umask就是系统可灵活配置的一种表现,umask改变的是创建文件时该文件的默认权限属性,后续如果想要修改,就可以用chmod指令。
那么如何修改umask呢?
非常简单,umask后面直接跟需要修改的值即可:
若此时我们创建一个文件:
因为凡是在umask中出现的权限,都不会在最终权限中出现,所以f1.txt的权限就全部变为-了。
4、文件删除
上图中,mydir这个目录的拥有者是blue用户(我),在我的目录下有一个root.txt文件,却不让我访问,而且你(root用户)还能在我的目录下随意访问root文件;在我的目录下,我自己不能访问而你却可以访问,这真是岂有此理!一怒之下,我直接给你删了,我们两个谁都不要访问,正所谓"我删你,与你何干!"。理是这个理,其实本质上是因为mydir这个目录的拥有者是blue,而且mydir对拥有者开放了w权限,如果有w权限,我们就可以删除mydir中的文件了。
结论:一个文件是否能被删除,与文件本身无关,与文件所处的目录的对应角色的w权限有关!
大家会不会觉得有点奇怪?你为什么能在我的家里建立你的文件呢?(不考虑超级用户,因为超级用户无视权限)
通常情况下,这种现象是不存在的,我们上面提到过两个普通用户是相互隔离的,用户1不可能进入用户2的家目录中,所以更不可能在用户2家目录中的目录下创建他的文件;特殊情况是用户1先变为超级用户进入用户2家目录下的某个目录中,然后再变回用户1,再创建他的文件,这时即便他可以这样,那么用户2也是有权利直接删除的,这种情况极少,所以大家也不必担心,反正你能建,我就能删。
现在,如果两个普通用户要进行文件级别的协作呢?
首先,这个文件不能放到任何一个私人账号中(一旦放到私人账号,那么另外一个人就拿不到这个文件了,何谈协作?),所以我们可以将这个文件放到私人账号(私人家目录)之外的地方,我们可以将这个文件建到根目录下。
在根目录下建立一个目录(共享目录)后,我们只需将这个目录的所有权限都打开,确保所有人都可以操作这个目录,然后用户1就可以在这个目录下建立一个文件,并把这个文件的所有权限打开,那么用户1和用户2都可以对这个文件进行操作了就可以达到协作的效果。
只有超级管理员才能在根目录下创建文件,普通用户是无法创建的:
普通用户对于根目录来说是other,other不具备w权限,故不能在根目录下创建文件。
有些人说根目录的拥有者是root,root也没有w权限啊,为什么root可以在根目录下建文件?这是因为root用户本就无视任何权限!一般来说,新建共享文件夹都是以root身份进行的!
大家看完后觉得有道理,这就可以解决文件无法协作的问题,但其实这样做是不妥的,我把这个文件的所有权限都打开,就相当于将这个文件共享了,这个系统中可能还有其他用户,比如说用户3、用户4、用户5...,那么问题就来了,其他用户也可以对用户1和用户2协作文件进行操作,如果其他用户把这个文件给删除了,好,完蛋!如果其他人不对这个文件进行操作,某一天,用户1和用户2发生矛盾了,用户2一气之下将这个文件给删除了,好,完蛋!
我们在根目录下新建一个共享文件后,由于它的权限全开,所以任何一个用户都可以操作这个目录:
所以,对于共享类文件,我们是不想让非文件的拥有者删除的!
为了防止文件被删除,我们可以将共享目录对other的w权限关闭,但是这样也是不行的,如果关闭other对该共享目录的w权限,那么其他人就不能在这个目录下新建文件,那么何谈共享性?
所以,我们必须将共享目录对other的w权限打开,所以我们的核心需求就是:任何人都能够在共享目录下新建文件,自己可以修改自己文件的权限属性,但是不允许此文件的非拥有者去删除该文件!!!
任何技术都是为了解决某种需求的。所以为了解决这个需求,Linux引入一个新的权限标志位:t,这个t我们称为粘滞位:
我们暂且不管t的作用,先看看它到底能不能解决我们的问题:
这个粘滞位的作用就是,在一个共享文件的情况下,不会让非拥有者删除这个共享文件,即便他对共享目录有w权限。(大家需要明白的一点是:共享文件在共享目录下)
只能给需要共享的目录添加粘滞位!
普通用户的家目录是在/home目录下的,在Linux系统中,除了普通用户的家目录是他自己的,其余的目录(比如根目录)都是root用户的,我们说过共享目录一般是建立在普通用户家目录之外的地方(通常是根目录下),所以要想建立这个共享目录前提需要是root用户,所以这个共享目录的拥有者通常是root用户。那么普通用户对于这个共享文件来说就是other,要约束普通用户,所以我们加粘滞位通常是加在other权限位置上的。粘滞位限制的是两个普通用户互相删除不了对方的文件,但是root用户天下无敌,谁的文件都能删。
在实际中,我们其实不需要单独创建一个共享文件。在根目录下,有一个tmp目录,它默认就有粘滞位t,我们可以将临时的共享文件放到tmp目录下即可:
我们在设置粘滞位时会遮挡该目录对于其他用户的x权限,粘滞位本身并不会直接影响other用户的执行(x)权限。如果你看到的是某个目录的“其他”用户的执行权限似乎被去除了,这可能是由于权限设置的变化,而不是粘滞位直接导致的。
六、结语
本篇内容到这里就结束了,主要讲了Linux文件的权限问题,希望对大家有帮助,祝生活愉快!
版权归原作者 心怀花木 所有, 如有侵权,请联系我们删除。