Linux 文件系统之 ls 命令引发的深思

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

Linux 操作系统想必大家都不陌生吧,它做的最好的地方就是轻量级的文件系统了,今天我们就来谈一谈。

ls 命令引发深思

linux 中我无意间使用了 ls -la 命令,产生了如下现象:

$ ls -la

drwxr-xr-x 14 root root     4096 Apr  3 18:47 .
drwxr-xr-x 23 root root     4096 Mar  2 05:48 ..
drwxr-xr-x  2 root root     4096 Apr  3 07:44 backups
drwxr-xr-x 17 root root     4096 Jul 22  2014 cache
drwxr-xr-x  2 root root     4096 Mar  2 04:26 docker-registry
lrwxrwxrwx  1 root root        9 Feb 25 13:31 lock -> /run/lock
drwxrwxr-x 15 root syslog   4096 Apr  3 07:44 log
-rw-r--r--  1 root root        0 Apr  3 18:47 test
复制代码
  • -l: long的简写,列举目录内容的细节,包括权限(模式)、所有者、组群、大小、创建日期、文件是否是到系统其它地方的链接,以及链接的指向。
  • -a: all 的简写,列举目录中的全部文件,包括隐藏文件。位于列表的起首处的 ..: 代表父目录 , .: 代表当前目录。

ls -la 输出了九列数据:

  • 第一列:表示文件或文件夹相应关系用户的操作权限
  • 第二列:表示文件夹内文件和文件夹的总数量(包括文件夹本身)
  • 第三列:表示文件夹或文件的拥有者
  • 第四列:表示文件或文件夹的所属的用户组
  • 第五列:表示文件或文件夹的大小,单位是 字节,递归计算子文件夹中文件的大小
  • 第六七八列:表示文件或文件夹最后被修改的时间
  • 第九列:表示文件或文件夹的名字

接下我们主要分析第一列的数据,拿上面的信息中倒数第二行 drwxrwxr-x 来进行分析,从左到右第一个字母表示文件系统对象的类别,这里 d 表示为目录(文件夹)。

  • 其它的值为:

    1. - (常规文件)
    2. d (目录)
    3. l (符号链接)
    4. c (字符特殊设备)
    5. b (模块特殊设备)
    6. p (FIFO)
    7. s (套接字)

drwxrwxr-x 除出去第一个字母 d 后,rwxrwxr-x 表示的是三种用户关系对文件或文件夹的操作权限。

从左到右每三个一组,依次表示 所有者权限组权限其他用户权限

每组的顺序均为 rwx,如果用户有相应的操作权限就用相应的字母表示,如果不具有相应的操作权限就用 - 表示。

比如: rwxrwxr-x 表示文件或文件夹的所有者具有rwx(可读,可写,可执行)的操作权限,组用户也具有rwx(可读,可写,可执行)的权限,其他用户具有r-x(可读,可执行,没有可读)的操作权限。

简单举例说明用户与文件权限的对应关系和如何查看之后下面我们介绍一下,如何更改文件的权限。

chmod 命令

chmod 修改文件权限有两种方式:

  • 字母法
  • 数字法

chmod 字母法的使用

角色说明:

角色 说明
u user, 表示该文件的所有者
g group, 表示用户组
o other, 表示其他用户
a all, 表示所有用户

权限设置说明:

操作符 说明
+ 增加权限
- 撤销权限
= 设置权限

权限说明:

权限 说明
r 可读
w 可写
x 可执行
- 无任何权限

不知道你有没有注意到这样一个现象:在命令行工具中, user 用户的权限是 $ 开头的; 管理员是 # 开头的。可以使用 whoami 查看当前用户。

拓展阅读:特殊权限SUIDSGIDSticky

linux 系统中还有三种与用户身份无关的三个文件权限属性。即SUIDSGIDSticky

  • SUID (Set User ID) :

    该属性只对有执行权限的文件有效,对目录无效。执行具有 SUID 权限的程序时,引发的进程的所有者是程序文件的所有者,而不是启动程序的用户(除非二者是同一个人)。比如,如果一个程序的所有者是root且具有SUID属性,一个普通用户执行此程序时,如同root执行此程序一样。(请注意该属性对Shell脚本程序无效)该属性为一些特殊程序(如lpr)的启动带来了方便。但有时也带来了安全隐患:比如一个具有SUID属性的程序如果在执行时运行了一个shell,那么用户可以籍此得到系统的最高权限。SUID可用 s 表示,如:

$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 47032 Feb 16  2014 /usr/bin/passwd
复制代码
  • SGID(Set Group ID) :

    对于可执行文件,SGIDSUID类似,引发的进程的所有组是程序文件所属的组。对于目录,SGID属性会使目录中新建文件的所属组与该目录相同。SGID也可以用 s 表示,如:

$ ls -l /var
drwxrwsr-x  2 root staff    4096 Apr 10  2014 local
drwxrwxr-x 15 root syslog   4096 Apr  4 19:57 log
复制代码
  • Sticky :

仅对目录有效。带 sticky 属性的目录下的文件或目录可以被其拥有者删除或改名。常利用 sticky 属性创建这样的目录:组用户可以在此目录中创建新文件、修改文件内容,但只有文件所有者才能对自己的文件进行删除或改名。如系统中的 /tmp 文件夹。在属性字符串中,通常用 t表示。

$ ls -l /
drwxrwxrwt   8 root root  4096 Apr  4 23:57 tmp
复制代码

修改文件或文件夹对应用户的操作权限

linux 系统中,可以使用chmod命令来修改文件或文件夹对应用户的操作权限,chmod 命令也有两种方式修改,一种是使用代表相应操作权限的字母简写表示,另一种是使用代表相应操作权限的数字表示。

使用字母简写

chmod 语法参数格式: [ugoa] [+-=] [rwxst]

  1. 第一个字符是 u、g、o、a: 分别表示 用户、组、其他人和所有人
  2. 第二个字符是 [+-=]: 分别表示 添加、删除和设置
  3. 第三个字符是 [rwxst]: 分别表示 读、写、执行和特殊权限

特殊权限意思参考上面的拓展阅读

范例演示:

  1. 给文件或文件夹 try 的拥有者加可执行权限
$ sudo chmod u+x try
复制代码
  1. 给文件或文件夹 try 的拥有者和组成员加可读可写权限
$ sudo chmod ug+rw try
复制代码
  1. 给文件或文件夹try的拥有者和组成员除去可写权限
$ sudo chmod ug-r try
复制代码

使用数字表示(八进制数)

为了简化表述,也可使用八进制数来表示权限。即用一个四位八进制数来表示,其中最高位表示特殊权限,随后的三位依次是所有者权限、组权限和其他人权限。每一个八进制位的权限数值是文件具有的相应权限所对应的数值之后,如:

0755 = rwxr-xr-x = 0(4+2+1)(4+0+1)(4+0+1)
复制代码

数值权限的算法,比如 rw- 其实就是 110 的二进制,也就是 0*2^0 + 1*2^1 + 1*2^2 = 6 。有相应的权限就用 1 表示,没有相应的权限就用 0 表示。不过这种算法特殊权限不包含在内。

范例演示:

  1. 给文件或文件夹 try 的拥有者加 rwx 权限,组用户加 r-x 权限,其他用户 r-- 权限
$ sudo chmod 0754 try
复制代码
  1. chmod 命令也可以递归的修改文件夹下所有的文件的权限,如给 try 文件夹下得所有文件加上 0755 权限
$ sudo chmod -R 0755 try
复制代码
  1. 批量只修改文件或文件夹权限
$ find -type d | xargs chmod 745     // 只修改文件夹权限
$ find -type f | xargs chmod 644     // 只修改文件权限

$ chmod 745 `find 路径 -type d`     // 只修改文件夹权限
$ chmod 644 `find 路径 -type f`     // 只修改文件权限
复制代码

相应权限的数值:

  1. rwx(7)、rw-(6)、r-x(5)、r--(4)、--wx(3)、-w-(2)、--x(1)、---(0)
  2. suid: 符号 s (4)
  3. sgid: 符号 s (2)
  4. sticky: 符号 t (1)

修改文件或文件夹的拥有者和所属的组

使用 chown 可以修改文件或文件夹的拥有者和所属的组

范例演示:

  1. 将文件或文件夹try的拥有者修改成aikin,所属的组修改成adm
$ sudo chown aikin:adm try
复制代码
  1. chmod 一样,-R 参数可以起到递归的作用
$ sudo chown -R aikin:adm try
复制代码

创建组和用户

组相关操作

  1. 创建一个aha_group
$ sudo groupadd aha_group
复制代码
  1. 修改 aha_group 组的名字为aha_group
$ sudo groupadd -n aha_group aha_group
复制代码
  1. 删除aha_group
$ sudo groupdel aha_group
复制代码
  1. 查看所有组
$ sudo cat /etc/group
复制代码

用户相关操作

  1. 创建用户 test

    linuxuseraddadduser 都可以用来创建用户,但是这两个命令是有区别的:

    • 使用useradd时,如果后面不添加任何参数选项,例如:$sudo useradd test 创建出来的用户将是默认 "三无" 用户:一无: Home Directory ,二无: 密码,三无: 系统 Shell

    • 使用 adduser 时,创建用户的过程更像是一种人机对话,系统会提示你输入各种信息,然后会根据这些信息帮你创建新用户。

所以创建用户建议使用 adduser 命令,它有以下参数:

选项 说明
-m 自动创建用户主目录,主目录的名字就是用户名
-g 指定用户所属的用户组,默认不指定会自动创建一个同名的用户组

不加参数的话就会出现下面默认的选项:

$ sudo adduser test

Adding user `test' ...
Adding new group `test' (1002) ...
Adding new user `test' (1001) with group `test' ...
Creating home directory `/home/test' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for test
Enter the new value, or press ENTER for the default
  Full Name []: test
  Room Number []:
  Work Phone []:
  Home Phone []:
  Other []:
Is the information correct? [Y/n] y
复制代码
  1. 修改用户
$ sudo passwd test    // 修改用户密码
$ sudo usermod -d /home/test -G try2 test   // 将test用户的登录目录改成/home/test,并加入 try 组,注意这里是大 G。
$ sudo gpasswd -a test try     // 将用户 test 加入到 try2 组。
$ sudo gpasswd -d test try2    // 将用户 test 从 try 组中移除
复制代码
  1. 删除用户test
$ sudo userdel test
复制代码
  1. 查看所有用户
$ cut -d : -f 1 /etc/passwd
// 或者
$ cat /etc/passwd | awk -F : '{print $1}'
复制代码

其实就是截取了 /etc/passwd 文件的每一行的第一个分号前面的数据