来自 ls -l 的输出可能包含清单中的第一个字符所显示的文件和目录以外的文件系统对象。本教程后面将会看到更多这样的对象,但就目前而言,只需那些最常见的对象类型。
代码 对象类型
- 普通文件
d 目录
l 符号链接
c 字符特殊设备
b 块特殊设备
p FIFO
s 套接字
更改权限
添加权限
假设创建一个 “Hello world” shell 脚本。在首次创建该脚本时,它通常无法执行。可以使用带 +x选项的 chmod命令来添加执行权限,如:
[ian@attic4-cent ~]$ echo 'echo "Hello world!"'>hello.sh
[ian@attic4-cent ~]$ ls -l hello.sh
-rw-rw-r--. 1 ian ian 20 Aug 8 22:18 hello.sh
[ian@attic4-cent ~]$ ./hello.sh
bash: ./hello.sh: Permission denied
[ian@attic4-cent ~]$ chmod +x hello.sh
[ian@attic4-cent ~]$ ./hello.sh
Hello world!
[ian@attic4-cent ~]$ ls -l hello.sh
-srwxrwxr-x. 1 ian ian 20 Aug 8 22:18 hello.sh
可以通过类似的方式使用 +r设置读权限,使用 +w设置写权限。事实上,您可以使用 r、w和 x 的任何组合。例如,使用 chmod +rwx会为文件设置所有读、写和执行权限。这种形式的 chmod 会添加还未设置的权限。
保持选择性
您可能在上面的示例中已注意到,我们为所有者、组和其他用户设置了执行权限。为了更具有选择性,您可以为模式表达式添加:
- 前缀 u来设置用户的权限,
- 添加前缀 g来为组设置用户权限,
- 添加前缀 o来为其他用户设置权限。
- 指定 a会为所有用户设置该权限,这等效于省略它。
下面的代码展示了如何向用户和组添加该 shell 脚本的另一个副本的写和执行权限。
[ian@attic4-cent ~]$ echo 'echo "Hello world!"'>hello2.sh**
[ian@attic4-cent ~]$ chmod ug+xw hello2.sh**
[ian@attic4-cent ~]$ ls -l hello2.sh
-rwxrwxr--. 1 ian ian 20 Aug 9 06:22 hello2.sh
删除权限
有时您需要删除权限,而不是添加它们。只需将 + 更改为 -,就可以删除任何已设置的指定权限。下面的代码展示了如何为其他用户删除这两个 shell 脚本上的所有权限。
[ian@attic4-cent ~]$ ls -l hello*.sh
-rwxrwxr--. 1 ian ian 20 Aug 9 06:22 hello2.sh
-rwxrwxr-x. 1 ian ian 20 Aug 8 22:18 hello.sh
[ian@attic4-cent ~]$ chmod o-xrw hello*.sh
[ian@attic4-cent ~]$ ls -l hello*.sh
-rwxrwx---. 1 ian ian 20 Aug 9 06:22 hello2.sh
-rwxrwx---. 1 ian ian 20 Aug 8 22:18 hello.sh
您一次可以更改多个文件上的权限, 可以使用 -R (或 --recursive)选项来递归地操作目录和文件。
设置权限
现在您已经可以添加或删除权限,您可能想知道如何仅设置一组特定的权限。可以使用 = 代替 + 或 -来实现此操作。要设置上述脚本上的权限,以便其他用户没有访问权,可以使用 chmod o= hello,而不是我们用于删除权限的命令。
如果您想为用户、组或其他用户设置不同的权限,可以使用逗号将不同表达式分开(例如 ug=rwx,o=rx),或者可以使用数值权限。
8421进制权限
之前您已使用符号(ugoa 和 rxw)指定权限。每个组中有 3 种可能的权限。也可以使用八进制数代替符号来设置权限。通过这种方式设置的权限最多使用 4 个八进制数。我们在讨论属性时将介绍第 1 个数。第 2 个书定义用户权限,第 3 个数定义组权限,第 4 个数定义其他权限。
这 3 个数中的每一个都通过添加想要的权限设置来构造:读 (4)、写 (2) 和执行 (1)。
在想要一次设置所有权限,而不为每个组提供相同的权限时,使用数值权限非常方便。可以使用 表 2 作为8421权限的方便参考。
符号 八进制
rwx 7
rw- 6
r-x 5
r-- 4
-wx 3
-w- 2
--x 1
--- 0
访问模式和S位程序
思考一个问题:/etc/shadow文件,它无法由普通用户直接更改,因为只有 root 用户能启用写权限。但是,在需要更改其密码时,普通用户需要能够以某种方式修改 /etc/shadow。所以,如果用户无法修改此文件,如何实现此目的?
root@ubuntu:/home/newer# ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 47032 Jan 26 2016 /usr/bin/passwd
suid 和 sgid
Linux 权限模型有两种特殊的访问模式,称为 suid(设置用户 id)和 sgid(设置组 id)。一个可执行程序设置了 suid 访问模式时,它运行起来就像是由文件的所有者启动的一样,而不是由真正启动它的用户启动的。类似地,在设置 sgid 访问模式后,该程序运行起来就像启动的用户属于该文件的组,而不是他自己的组。可单独或同时设置两种访问模式。
请注意,用户的权限三元组中的 x被 s 替代。这表明对于这个特定的程序,设置了 suid 和可执行位。所以当 passwd 运行时,它执行起来就像具有完整的超级用户访问权的 root 用户启动了它,而不是运行它的用户启动 它。因为 passwd 使用 root 访问权运行,所以它可以修改 /etc/passwd。suid 和 sgid 位占用了长目录清单中针对用户和组的 x
位。如果该文件是可执行的,suid 或 sgid 位(如果已设置)将显示为小写的 s。否则,它们显示为大写的 S。
尽管 suid 和 sgid 使用起来很方便,甚至在许多情况下必不可少,但是,如果不在当地使用这些访问模式,可能破坏系统的安全性。您拥有尽可能少的 suid 程序。passwd命令是为数不多的必须 为 suid 的程序之一。
设置 suid 和 sgid
suid 和 sgid 位使用字母 s以符号方式设置和重新设置。例如,u+s
设置 suid 访问模式,g-s 删除 sgid 模式。在八进制格式中,suid 在第一个(高阶)数中具有值 4,而 sgid 具有值 2。
目录和 sgid
当一个目录启用了 sgid 模式时,其中创建的任何文件或目录都将继承该目录的组 ID。这对一组参与同一个项目的人使用的目录树特别有用。
下图 展示了用户 greg 如何设置 development 组的所有用户都可以访问的一个目录,以及用户 jenni 在该目录中创建一个文件的示例。在完成创建之后,文件 jenni.txt 允许组成员写入该文件,所以 jenni 使用 chmod g-w
来禁用组写入功能。
[jenni@attic4-cent ~]$ su - mary
Password:
[mary@attic4-cent ~]$ **echo "something" >> ~greg/lpi101/jenni.txt**-bash: /home/greg/lpi101/jenni.txt:
Permission denied
[mary@attic4-cent ~]$ rm ~greg/lpi101/jenni.txt**rm:
remove write-protected regular empty file `/home/greg/lpi101/jenni.txt'? y
[mary@attic4-cent ~]$ **ls -l ~greg/lpi101
total 0
粘滞位
你刚看到了拥有一个目录的写权限的用户如何删除其中的文件。这对组项目而言是可以接受的,但它对全局共享的文件空间(比如 /tmp 目录)而言不太合意。幸运的是,有一个相关的解决方案。
剩余的访问模式位被称为粘滞 位。它们在符号上由 t 表示,在数值上由高阶八进制数中的 1 表示。它在一个长目录清单中显示在其他用户的可执行标志中(最后一个字符),大写和小写对 suid 和 sgid 具有相同的含义。
如果这个位是为一个目录设置的,它仅允许所有者用户或超级用户 (root) 删除或取消链接一个文件。
下面展示了用户 greg 如何在他的 lpi101 目录上设置粘滞位,还表明这个位是为 /tmp 设置的。
访问模式摘要
访问模式 符号 八进制
suid s with u 4000
sgid s with g 2000
sticky t 1000
将此信息与之前的权限信息相结合,您就可以看到与 greg 的 lpi101 权限对应的完整的八进制表示,而且 drwxrwsr-t 的访问模式为 3775
ls -l 命令不能显示文件的8421 权限,可以通过find命令来看看。
[greg@attic4-cent ~]$ find . -name lpi101 -printf "%M %m %f\n"
drwxrwsr-t 3775 lpi101
lsatr 和 chatr
在Linux中,提供了一种方式chatr +i 来锁定文件,这个时候即使是root,在没有去掉该属性之前,也不能对其进行操作。
[root@attic4-cent ~]# touch keep.me
[root@attic4-cent ~]# chattr +i keep.me
[root@attic4-cent ~]# lsattr keep.me
----i---------- keep.me
[root@attic4-cent ~]# rm -f keep.me
rm: cannot remove `keep.me': Operation not permitted
[root@attic4-cent ~]# chattr -i keep.me
[root@attic4-cent ~]# rm -f keep.me
文件创建掩码
创建新文件时,创建进程会指定新文件应拥有的权限。通常,请求的模式为 0666,它使该文件可由任何人读和写。目录的模式默认情况下通常为 0777。但是,这种宽容性创建会受到一个 umask 值的影响,该值指定用户不想向新创建的文件或目录自动授予哪些权限。系统使用 umask 值来减少最初请求的权限。您可以使用 umask 命令查看 umask 设置。
请记住,umask 指定哪些权限不应授予
[ian@attic4-cent ~]$ umask -S**u=rwx,g=rwx,o=rx
[ian@attic4-cent ~]$ umask u=rwx,g=,o=
[ian@attic4-cent ~]$ umask 0077
[ian@attic4-cent ~]$ touch newfile
[ian@attic4-cent ~]$ **ls -l newfile
-rw-------. 1 ian ian 0 Aug 9 07:09 newfile
新创建的文件的默认权限为 0666,而且 umask 值指定其中哪些位应删除(屏蔽掉)。所以如果您想要执行权限,必须将它显式添加到文件中。