文件权限 —— shell 笔记

文件权限 —— shell 笔记

文件权限符

先回顾一下 ls -l 的输出:

ls 输出

输出结果的第一个字段就是描述文件和目录权限的编码。这个字段的第一个字符代表了对象的类型:

  • - 代表文件
  • d 代表目录
  • l 代表链接
  • c 代表字符型设备
  • b 代表块设备
  • n 代表网络设备

之后有 3 组三字符的编码。每一组定义了 3 种访问权限:

  • r 代表对象是可读的
  • w 代表对象是可写的
  • x 代表对象是可执行的

若没有某种权限,在该权限位会出现单破折线。这 3 组权限分别对应对象的 3 个安全级别:

  • 对象的属主
  • 对象的属组
  • 系统其他用户

文件权限符

如上图,_config.yml 文件有下面 3 组权限:

  • rw- 文件的属主 frank
  • r-- 文件的属组 staff
  • r-- 系统上其他用户

默认文件权限

这些文件权限从何而来?答案是 umaskumask 命令用来设置所创建文件和目录的默认权限。

$ touch newfile
$ ls -l newfile
-rw-r--r--  1 frank  staff  0 Oct  7 21:50 newfile
$ umask
0022

touch 命令用分配给我的用户账户的默认权限创建了这个文件。umask 命令可以显示和设置这个默认权限。如上面代码所示,当前的默认权限为 0022。第一位代表了一项特别的安全特性,叫作粘着位(sticky bit),后面的 3 位表示文件或目录对应的 umask 八进制码:

权限二进制值八进制码描述
---0000没有任何权限
--x0011只有执行权限
-w-0102只有写入权限
-wx0113有写入和执行权限
r--1004只有读取权限
r-w1015有读取和执行权限
rw-1106有读取和写入权限
rwx1117有所有权限

八进制模式先取得权限的八进制值,然后再把这三组安全级别(属主、属组和其他用户)的八进制值顺序列出。因此,八进制模式的值 664 代表属主和属组成员都有读取和写入的权限,而其他用户都只有读取权限。

这里就有个疑问了,系统上默认的八进制的 umask 值是 0022 ,而我所创建的文件的八进制权限却是 644 (rw-r–r–),这是如何得来的呢?

umask 值只是个掩码。它会屏蔽掉不想授予该安全级别的权限。接下来我们还得再多进行一些八进制运算才能搞明白来龙去脉。

具体说来,就是要把 umask 值从对象的全权限值中减掉。对文件来说,全权限的值是 666 (所有用户都有读 和写的权限);而对目录来说,则是 777 (所有用户都有读、写、执行权限)。所以在上例中,文件一开始的权限是 666,减去 umask 值 022 之后,剩下的文件权限就成了 644。

可以用 umask 命令为默认 umask 设置指定一个新值。

$ umask 026
$ touch newfile2
$ ls -l newfile2
-rw-r-----  1 frank  staff  0 Oct  7 22:14 newfile2

改变权限

chmod 命令用来改变文件和目录的安全性设置:

chmod options mode file

mode 参数可以使用八进制模式也可使用符号模式进行安全性设置。当然,八进制模式设置非常直观,直接用期望赋予文件的标准 3 位八进制权限码即可。

$ ls -l newfile
-rw-r--r--  1 frank  staff  0 Oct  7 21:50 newfile
$ chmod 760 newfile
$ ls -l newfile
-rwxrw----  1 frank  staff  0 Oct  7 21:50 newfile

使用符号模式需要对应 (1) user (2) group (3) others 三种身份,我们用 u, g, o 来代表三种身份的权限,此外,a 则代表 all 亦即全部的身份!读写和执行的权限用 r, w, x 表示:

chmodu
g
o
a
+ (加入)
- (除去)
= (设定)
r
w
x
file

例如如果我们不知道原先的文件属性,而只想要增加 .bashrc 这个文件的所有用户均可写入的权限, 那么就可以使用:

chmod  a+w  .bashrc

改变所属关系

chown 命令用来改变文件的属主, chgrp 命令用来改变文件的默认属组。

chown 命令的格式如下:

chown options owner[.group] file

可用登录名或 UID 来指定文件的新属主,chown 命令也支持同时改变文件的属主和属组,也可以只改变一个目录的默认属组。

$ chown chris newfile
$ chown chris.shared newfile
$ chown .newgroup newfile

但需要注意,只有 root 用户能够改变文件的属主。任何属主都可以改变文件的属组,但前提是属主必须是原属组和目标属组的成员。

avatar

Frank Lin

Code learning...