About Blog Contact

Linux文件权限总结

什么是文件权限

Linux是一个多用户(user)操作系统。用户对文件(file)所能进行的操作是有限制的,什么用户能进行什么操作,这就是文件的权限(permission)。

对文件进行的操作有三种:

这三者从技术上说都是调用Linux内核的系统调用(system call)。在使用open系统调用得到文件描述符后可以使用readwrite进行有关操作。

对某个文件,不同的用户所能进行的操作可以不同。比如/home/toad/文件夹下面的文件,应当设置为只有用户toad可见;/var/www/html文件夹下的文件只用运行网页服务器的用户www-data可以读写;而/usr/bin/下面的可执行文件,所有用户都可以执行,但只有管理员用户可以改动。

我们可以对用户权限作细致的设置,让每个用户对某个文件都有不同的权限。不过一般情况下我们只需要把所有的用户分为三类,对这三类用户分别进行设置:

文件权限的表示

这样看来,一个文件的权限其实一共有九个参数:三类用户的读、写、执行权限。在文件系统中,是作为一个12bit的参数存储的(不是9bit,因为其实不止9个参数……我们先忽略那三个参数,那三个也不常用)。通常用如下的格式表示(比如ls -l命令的返回格式):

$ ls -l pskeys
-rw-r--r-- 1 root toads 1839 8月   3 16:27 pskeys

“-rwxr–r–“表示文件pskeys的权限。第一个连字符表示这是个一般文件,不是文件夹。第2到第4个字符rwx表示所有者root的权限:可读可写可执行。第5到第7个字符r--代表的是文件的组(group)toads里面的其他用户的权限,可读不可写不可执行。8到10的意思自然很清楚了:其他所有用户可读不可写不可执行。r,w,x三个字符分别表示read,write和executable。

要注意的是,三种用户的权限设置是独立的。可以把文件设置成所有者不能读写,然而别人可以读写。而且,文件的组和文件的所有者可以没有关系,文件的所有者可以不在组里面。就算是在的话,所有者的权限也是由第一项决定的,和之后组的权限没有关系。

还有一种更简短的表示方法,在chmod命令中会用到。读,写,执行权限的组合共有8种,我们用0到7八个数字分别表示。rwx对应7,—对应0,r–对应4,rw-对应6,如下表所示:

权限 数字
rwx 7
rw- 6
r-x 5
r– 4
-wx 3
-w- 2
–x 1
0

文件权限的设置

一般用chmod指令设置文件权限。

这样,

chmod 666 /dev/ttyUSB0

的意思就是/dev/ttyUSB0串口文件设置为所有用户可以读可以写不可执行(当然root除外,root无论怎么设置都是想干什么干什么)

chmod 744 somefile

则是所有者对somefile拥有所有权限,而别人只可以读。

不过,用数字指定指令的方式其实不太好。最好用符号模式指定权限:

chmod u+x,go=r somefile

给所有者(u)增加执行权限,不改变所有者其他已经有的权限;把组用户(g)和其他用户(o)的权限设置为只读。

chmod a-w somefile

取消所有用户(a)读的权限。

最好只用+和-,毕竟如果用=指令的话,可能一不留神你就把一个你没有注意到的权限给弄没了。

chmod还有几个额外的功能。-R 选项可以递归的设置一个文件夹的所有文件。别的功能我觉得就不常用了。

关于文件夹的补充

文件夹的权限和文件略有不同,如下表所示。

要注意,对文件夹而言,更改子文件内容需要的文件夹权限不是写权限,而是执行权限。写访问意味着创建或删除文件的能力,与文件本身的权限完全无关紧要。仔细想想,添加文件时,你在做什么? 你在文件夹目录列表中添加了一个新条目,更改了文件夹,因此你需要对该文件夹具有写入权限。 删除时的情况相同。因此如果您具有写访问权限,则无论文件本身的权限如何都可以这样做。

当然,更改/获取文件内容时,文件也要有相应读/写权限。不可读写的文件,就算文件夹有执行权限,也是不可读写的。

而且,文件夹的权限是不继承的。里面新建的文件和文件夹的权限,不加额外的参数的话就是默认值。

其实,没谁闲得没事瞎设置权限……默认值一般够用了……

sticky bit和 setuid bit

文件和文件夹还有三个特殊的权限。我们先说sticky bit。我们看看/tmp文件夹的权限:

$ ls -ld /tmp
drwxrwxrwt 15 root root 4096 8月  16 18:38 /tmp

对root用户和root组之外的用户,执行的那一项怎么不是x,而是t呢?这就是额外的sticky bit。这样,用户就不能删除自己不是所有者的文件了,纵使对这个文件夹有写和执行权限。对/tmp这种所有人都能读写的文件夹,万一某个用户的程序把别的用户的程序存的临时文件给删除了,那就不好了。

文件的话,sticky bit的作用类似,不过一般用不上,直接设定用户的权限就行了。

下面再说setuid bit,和类似的setgid bit。我们看ping命令对应的程序文件/bin/ping的权限:

$ ls -l /bin/ping
-rwsr-xr-x 1 root root 64424 3月  10  2017 /bin/ping

怎么在执行的位置有个s呢?这就是setuid bit了。setuid bit的意思是,这个程序在执行的时候,无论被谁执行,都是以所有者的身份执行的。ping程序所有用户都有执行权限。然而,ping需要root权限才能访问有关网络接口。有了setuid bit之后,非root用户执行ping的时候,访问各种资源的权限就和root一样了。

setgid bit 类似,程序文件有了setgid bit后,在别的用户执行他的时候,访问各种资源的权限就和程序所在的组一样了。

在设置的时候,可以用chmod的符号模式。setuid bit 和setgid bit 都是s。sticky bit 是t,语法和之前一样。用数字模式的话,在三位数前面要加一位。setuid是4,setgid是2,sticky bit 是1。这样,

chmod 6711 file

后,文件的权限是

-rws--s--x

还记得我之前说数字模式不好吗?就是因为这三个flag的存在。如果之后执行

chmod 711 file

的话,权限就变了:

-rwx--x--x

setuid和setgid都消失了!其实,711的隐含意思是0711,这样两个bit消失也不奇怪。所以,如果你执行类似

chmod -R 777 /

的话,会导致所有文件的这两个权限都消失了!整个系统都会崩溃的。

对文件夹的话,setuid,setgid的意义又有所不同。如果文件夹的setgid被设定了的话,所有在文件夹中新建的文件的组都会被设置为该文件夹的组。而且,这些文件夹的setgid会继承自己祖先的,除非在新建时明确说明。对文件夹而言,setuid一般会被忽略,我们就不管了。而且,和文件不一样的是,在chmod时,类似

chmod 777 dir

的指令,是不会改变其gid和uid的!蛋疼吧!

总结

最好使用符号模式,用+-最好。一般情况下默认值就够了,不要瞎改系统的权限。 我现在唯一遇到需要改权限的地方就是ssh的密钥文件需要设置一下。

参考资料