文件权限与属性
查看权限[编辑 | 编辑源代码]
使用ls命令的-l
选项查看为目录内容设置的权限(或文件模式),例如:
$ ls -l /path/to/directory
total 128 drwxr-xr-x 2 archie users 4096 Jul 5 21:03 Desktop drwxr-xr-x 6 archie users 4096 Jul 5 17:37 Documents drwxr-xr-x 2 archie users 4096 Jul 5 13:45 Downloads -rw-rw-r-- 1 archie users 5120 Jun 27 08:28 customers.ods -rw-r--r-- 1 archie users 3339 Jun 27 08:28 todo -rwxr-xr-x 1 archie users 2048 Jul 6 12:56 myscript.sh
第一栏是我们必须关注的内容。 以 drwxrwxrwx +
为例,每个字符的含义在下表中说明:
d
|
rwx
|
rwx
|
rwx
|
+
|
文件类型,技术上不属于其权限。 有关可能值的说明,请参阅 info ls -n "What information is listed" 命令的输出。
|
所有者对文件的权限,如下所述。 | 该组对该文件的权限,如下所述。 | 所有其他用户对该文件的权限,如下所述。 | 一个指定备用访问方法是否适用于该文件的字符。 当此字符是空格时,没有备用访问方法。 . 字符表示具有安全上下文的文件,但没有其他备用访问方法。 具有任何其他备用访问方法的文件用 + 字符标记,例如在使用访问控制列表 (ACL) 的情况下.
|
权限三元组(也就是上面例子中的rwx
)可以由以下字符(权限位)构成:
字符 | 文件效果 | 目录效果 | |
---|---|---|---|
读权限(第一个字符) | -
|
不能读取该文件 | 不显示目录里的内容 |
r
|
可以读取该文件 | 能显示目录里的内容 | |
写权限(第二个字符) | -
|
不能修改该文件 | 不能修改目录中的内容 |
w
|
可以修改该文件 | 能修改目录中的内容(创建、重命名或删除文件或子目录);需要同时设置执行权限,否则本权限无效。 | |
执行权限(第三个字符) | -
|
不能执行该文件 | 无法使用 cd 命令访问该目录 |
x
|
可以执行该文件 | 能使用 cd 命令访问该目录。这是实践中唯一一个算是可以从父目录继承而来的权限。实际上,如果某文件或目录路径中的任何一个目录没有设置 x 权限, 就算最终访问的文件或目录设置了对应的权限也是打不开的。请参考path_resolution(7) 来了解更多。 | |
s
|
当出现在用户(所有者)权限三元组时,代表 setuid 位; 当出现在组权限三元组时,代表 setgid 位;不会出现在对其他用户权限的三元组中;同时意味着设置了 x 权限。
| ||
S
|
与 s 相同,但是未设置 x 权限;普通文件中很少见,并且对于目录是无效的。
| ||
t
|
粘滞位,只存在于对其他用户权限的三元组中;同时意味着设置了 x 权限。
| ||
T
|
与 t 相同,但是未设置 x 权限 ;普通文件中很少见。
|
请参考 info Coreutils -n "Mode Structure"
和 chmod(1) 以获得更详细的说明。
namei -l path
命令查看文件或者目录沿路的权限案例[编辑 | 编辑源代码]
让我们用一些案例来解释说明:
drwx------ 6 archie archie 4096 Jul 5 17:37 Documents
Archie 具有对 Document
目录的完全访问权限。它可以列出、创建和重命名或删除 Documents 中的任何文件,无论其中文件的权限是什么。而它访问文件的能力取决于具体文件的权限。
dr-x------ 6 archie archie 4096 Jul 5 17:37 Documents
Archie 拥有完全访问权限,但他们不能创建、重命名或删除任何文件。他们可以列出文件,并且(如果文件的权限允许)可以访问文档中的现有文件。
d-wx------ 6 archie archie 4096 Jul 5 17:37 Documents
Archie 不能在 files
目录中执行 ls
,但是如果它知道现有文件的名称,就可以列出、重命名、删除或(如果文件的权限允许)访问该文件。此外,它们还能够创建新文件。
d--x------ 6 archie archie 4096 Jul 5 17:37 Documents
Archie 只能够在文件权限允许的情况下访问已知的文件。它不能列出目录中的文件,也无法创建、重命名或者删除任何文件。
要记得,我们在此介绍的是目录权限,这与单个文件权限无关。创建一个新文件时,修改的是目录。这就是为什么您需要有目录的写权限。
接下来我们看一些文件权限方面的例子:
-rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar
在这里,我们可以看到第一个字母不是 d
而是 -
。所以我们知道它是一个文件,而不是一个目录。接下来,所有者的权限是rw-
。所有者并没有拥有全部的三个权限可能很奇怪,但这个文件作为一个文本文件而不是一个可执行文件时,并不需要x
权限(但如果它包含 python 代码之类的内容,那么它很可能是可执行文件),我们可以用 Gedit、EMACS 等文本编辑器或者 R 之类的软件来读取它。该文件的组权限为 r--
,因此该组的成员可以读取文件,但不能以任何方式对其进行写入/编辑,实际上就是把它设置为只读。最后是对其他用户的权限,被设置为与组权限一致,也是只读。
修改权限[编辑 | 编辑源代码]
chmod 是 Linux 和其他 Unix-like 操作系统中用来修改文件或者目录权限的命令。
以字符形式修改权限[编辑 | 编辑源代码]
想要修改文件的权限(或者叫访问模式),请在终端里使用 chmod 命令。以下是该命令的基本结构:
chmod who=permissions filename
其中的 who
是一个或者多个字母,代表要指定权限的对象,可以为:
权限和上面 #查看权限所述的相同 (r
, w
和 x
).
现在看一下使用这个命令的一些示例。假设您对“文档”目录进行了严格的保护,并希望拒绝除您之外的所有人在其中读取、写入和执行(或在本例中是拒绝搜索或查看)的权限。
修改前: drwxr-xr-x 6 archie web 4096 Jul 5 17:37 Documents
$ chmod g= Documents $ chmod o= Documents
修改后: drwx------ 6 archie web 4096 Jul 6 17:32 Documents
在这里,因为您想要禁止所有权限,所以不要在 =
后面输入任何内容。如此修改后,除了文件所有者的权限为 rwx
之外,其他权限都是 -
。
您可以使用如下命令来恢复原来的状态:
再次修改前:drwx------ 6 archie web 4096 Jul 6 17:32 Documents
$ chmod g=rx Documents $ chmod o=rx Documents
再次修改后:drwxr-xr-x 6 archie web 4096 Jul 6 17:32 Documents
在下一个例子中,您想给组及其他用户读取和执行权限,所以您可以在 =
后面输入相应的权限 r
和x
,记得不要带空格。
您可以在 who
的地方输入多个字母,来同时给多个对象设置权限,如:
$ chmod go=rx Documents
chmod
命令中的 who
字母或者权限位(
)字符的顺序是无关紧要的。chmod go=rx file
和 chmod og=xr file
这两个命令的含义完全相同接下来我们考虑第二个例子,假设您想让自己和 web
用户组中的用户(可能是您的同事)有 foobar
这个文件的读写权限, 但其他人只能读取它。那么操作如下:
修改前: -rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar
$ chmod g=rw foobar
修改后:-rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar
这与第一个示例完全相同,但使用的是文件,而不是目录,并且您授予的是写入权限(这只是为了给出授予每个权限的示例)。
字符形式的捷径[编辑 | 编辑源代码]
chmod 命令允许使用 +
或 -
而不是=
从现有集合中添加和减去权限。这与上面的命令不同,后者实质上是重设权限(例如,要将权限从r--
更改为rw-
,您仍然需要在 chmod 命令的=
之后包含 r
和 w
。如果遗漏了r
,那么在使用=
重设权限时,它将取消r
的权限。使用+
和-
可以通过添加或删除当前的权限集来避免这种情况)。
让我们用 +
和 -
的方式复现一下前面给组添加写权限的例子:
修改前: -rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar
$ chmod g+w foobar
修改后:-rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar
另一个例子,取消所有用户和组的写入权限。
修改前: -rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar
$ chmod a-w foobar
修改后: -r--r--r-- 1 archie web 5120 Jun 27 08:28 foobar
另一个不同的捷径是特殊的 X
模式:实际上不存在这个模式,但它通常与 -R
选项(递归)一起使用,以设置只针对目录的执行权限,而不修改常规文件的权限,例如:
$ chmod -R a+rX ./data/
复制权限[编辑 | 编辑源代码]
您可以让 chmod 把某对象(比如所有者)的权限复制给其他对象(比如组或者所有人)。想要做到这一点,在 =
后面不要跟权限(r
、w
和x
),而是输入另一个 who 字母。比如:
修改前 -rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar
$ chmod g=u foobar
修改后 -rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar
这个命令的意思就是「把对组(g=
)的权限设置为与所有者(=u
)的权限相同」。请注意,您不能复制一组权限,也不能授予新的权限,以下是错误示范,chmod 会报错:
$ chmod g=wu foobar
数字形式[编辑 | 编辑源代码]
chmod 也可以用数字来设置权限。
使用数字是另一种方法,它允许您同时编辑所有者、组和其他人的权限,以及setuid、setgid和粘滞位。命令的基本结构如下:
$ chmod xxx filename
xxx
部分是一个三位数,其中的每一位可以是0到7之间的任何数字。第一位数字指所有者的权限,第二位数字指组的权限,而第三位数字指所有其他人的权限。
在这个数字表示法中,权限 r
、w
和x
所对应的数值是:
r=4 w=2 x=1
要得到这个三位数,您要考虑为所有者、组和所有其他人设置哪些权限,然后将其对应的数值累加起来。例如,如果希望授予目录的所有者读写和执行权限,并希望 group 和其他所有人只有读写权限,那么通过计算可以得到如下数值:
- 所有者:
rwx
=4+2+1=7 - 组:
r-x
=4+0+1=5 - 其他人:
r-x
=4+0+1=5
$ chmod 755 filename
这就相当于使用如下命令:
$ chmod u=rwx filename $ chmod go=rx filename
若要以数字形式查看文件或目录的现有权限,请使用stat(1)命令:
$ stat -c %a filename
%a
指定以数字形式输出文件权限。
大多数目录被设置为 755
以允许所有者读取、写入和执行,但拒绝被其他所有人写入;文件通常是644
以允许所有者读取和写入,但允许其他所有人读取;请参考最后一个关于不可执行文件缺少x
权限的说明,此处同理。
为了用实例来说明这一点,我们用数字方式复现一下前面举过的例子:
修改前:-rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar
$ chmod 664 foobar
修改后: -rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar
如果这是一个可执行文件,同时您想向所有者和组授予可执行权限,则权限数字为774
。或者,如果您希望每个人都只具有读取权限,则数字将为444
。将r
视为4,w
视为2,以及x
视为1,这可能是计算chmod xxx 文件名
的权限数值最简单的方法。
但还有一种二进制方法,其中每个权限都代表一个二进制数,最后再将其转换为一个数字。它有点复杂,但为了完整起见,在此也介绍该方法。
对于以下权限组合:
-rwxrwxr-x
如果您在每个授予的权限下写1,而在每个未授予的权限下写0,则结果如下:
-rwxrwxr-x 111111101
然后把它当成二进制数进行转换:
000=0 100=4 001=1 101=5 010=2 110=6 011=3 111=7
因此,上述值为775。
如果我们想从组中删除写权限:
-rwxr-xr-x 111101101
因此,该值将为755,您可以使用 chmod 755 文件名
删除可写权限。无论使用哪种方法,您最终都会得到相同的三位数。使用文本还是数字取决于个人偏好和打字速度。如果您希望将目录或文件还原为默认权限(例如所有者有读写和执行权限,但拒绝其他所有人的写权限),则使用chmod 755/644 文件名
可能会更快。但如果您要将权限更改为比较少见的组合,则使用文本方法可能会更简单、更快,而不是尝试将其转换为数字,这可能会导致错误。对于只需要偶尔使用chmod的用户来说,这两种方法的速度都没有显著的差异。
您也可以用数字形式设置setuid
, setgid
和 sticky
权限位。
setuid=4 setgid=2 sticky=1
比如 chmod 2777 filename
将为每个人设置读/写/可执行位,并启用setgid
位。
批量 chmod[编辑 | 编辑源代码]
通常,目录和文件不应具有相同的权限。如果需要批量修改目录树,请使用find选择性地修改其中一个或另一个。
若要只把目录权限修改为 755:
$ find directory -type d -exec chmod 755 {} +
若要只把文件权限修改为 644:
$ find directory -type f -exec chmod 644 {} +
修改所有者[编辑 | 编辑源代码]
chown 能够修改文件或者目录的所有者,这在某些情况下会更简单快捷。
比如,您要使用GParted为备份数据创建一个新分区。Gparted以root身份执行所有操作,因此默认情况下所有内容都属于root。这一切都很好,但当要向挂载的分区写入数据时,常规用户会没有权限。
brw-rw---- 1 root disk 8, 9 Jul 6 16:02 sda9 drwxr-xr-x 5 root root 4096 Jul 6 16:01 Backup
若您所见,/dev
是由root所有的,而挂载点(/media/Backup
也是一样。如果我们要修改挂载点的所有者,您可以执行如下命令:
修改前: drwxr-xr-x 5 root root 4096 Jul 6 16:01 Backup
# chown archie /media/Backup
修改后: drwxr-xr-x 5 archie root 4096 Jul 6 16:01 Backup
现在在无需调整权限的情况下,这个分区就可以由新的所有者 archie 写入了。(作为所有者,它本身就拥有 rwx
权限)
chown
总是会清除 setuid 和 setgid 权限位- 非 root 用户不能使用
chown
来把他们自己拥有的文件「送给」其他用户
访问控制列表(ACL)[编辑 | 编辑源代码]
Access Control Lists 通过允许为任何用户或组设置对任何文件的权限,为文件系统提供了额外的、更灵活的权限机制。
Umask[编辑 | 编辑源代码]
umask 实用程序用于控制文件创建模式掩码,该掩码确定了新创建文件的权限位的初始值。
文件属性[编辑 | 编辑源代码]
除了控制用户和组读、写和执行权限的文件权限之外,还有几个文件系统支持文件属性,这些属性可以进一步自定义允许的文件操作。
e2fsprogs包 软件包内有 lsattr(1) 和 chattr(1) 这两个可以列出和修改文件属性的工具。
以下是一些有用的属性,但并非所有的文件系统都支持每个属性。
a
- 仅追加(append only):文件只能以追加的方式打开。c
- 压缩(compressed):为文件启用文件系统级的压缩。i
- 不变(immutable):无法被修改、删除、重命名或创建指向它的链接。只能由root用户设置。j
- 数据日志(data journaling):为文件的写入和元数据启用日志。m
- 不压缩(no compression):为文件禁用文件系统级的压缩。A
- 禁用atim更新(no atime update):文件的 atime (访问时间)将不会被修改。C
- 禁用写时拷贝(no copy on write): 对于支持写时拷贝的文件系统,禁用写时拷贝。
查看 chattr(1) 以获得更详细的文件属性列表以及它们的作用。
比如,如果您想给某个文件设置不变(immutable)属性,使用如下命令:
# chattr +i /path/to/file
要删除文件上的属性,只需把 +
改为 -
。
扩展属性[编辑 | 编辑源代码]
根据 xattr(7):「扩展属性是与文件和目录永久关联的键值对」。有四个扩展属性类: security、 system、 trust 和 user。
扩展属性还用于设置能力(Capabilities).
用户扩展属性[编辑 | 编辑源代码]
用户扩展属性可用于存储有关文件的任意信息,比如:
$ setfattr -n user.checksum -v "3baf9ebce4c664ca8d9e5f6314fb47fb" foo.txt
使用getfattr来显示扩展属性:
$ getfattr -d foo.txt
# file: foo.txt user.checksum="3baf9ebce4c664ca8d9e5f6314fb47fb"
如果要删除扩展属性:
$ setfattr -x user.checksum foo.txt
保留扩展属性[编辑 | 编辑源代码]
命令 | 所需的选项 |
---|---|
cp |
--preserve=mode,ownership,timestamps,xattr
|
mv |
默认会保留[注 1] |
tar |
创建tar档时用 --xattrs ,解压时用 --xattrs-include='*'
|
bsdtar |
解压时用 -p
|
rsync | --xattrs
|
- ↑ 当目标文件系统不支持扩展属性时,mv 会静默地丢弃这些扩展属性。
要在使用文本编辑器的时候保留扩展属性,您需要把他们配置为在保存时截断(truncate)文件而非使用 rename(2).[1]
技巧和窍门[编辑 | 编辑源代码]
Preserve root[编辑 | 编辑源代码]
使用 --preserve-root
选项来阻止 chmod
递归地从 /
修改文件权限。 这可以防止在系统范围内删除可执行位,从而破坏系统。要每次使用此标志,请在alias中设置它。参见 [2].