Skip to content

02 贴在身上的标签 - 文件的权限与属性

文件的类型和权限

4dda06e4-0fca-4721-b0e2-00125112875b

文件类型

  • -: 普通文件
  • d: 目录
  • l: 符号链接
  • b: 块设备
  • c: 字符设备
  • p: 管道
  • s: 套接字

文件权限

Linux 系统的文件权限分为三组,每组三位:

  • 所有者权限(Owner):文件所有者的权限。
  • 组权限(Group):文件所属组的成员的权限。
  • 其他用户权限(Others):既不是文件所有者,也不在文件所属组中的其他用户的权限。

每组权限包含三种类型:

权限类型说明权限码数字表示
读(Read)允许查看文件内容或列出目录内容r4
写(Write)允许修改文件内容或添加、删除目录中的文件w2
执行(Execute)允许执行文件(如果它是一个脚本或二进制文件)或进入目录x1

查看文件权限

使用 ls -l 命令可以查看文件或目录的权限:

bash
> ls -l filename
-rwxr-xr-- 1 user group 4096 Mar 10 10:00 filename
  • 第一个字符 - 表示这是一个普通文件(d 表示目录)。
  • 接下来的三个字符 rwx 表示用户(所有者)的权限:读、写、执行。
  • 中间的三个字符 r-x 表示组的权限:读、执行。
  • 最后的三个字符 r-- 表示其他用户的权限:读。

文件读写权限修改 chmod

chmod(change mode)命令用于修改文件或目录的权限。

bash
chmod [选项] 权限模式 文件名

常用选项:

  • -R: 递归修改,即修改指定目录下所有子目录和文件的权限

字母方式

标识符说明
u所有者权限
g组权限
o其他用户权限
a所有权限(所有者、组和其他用户)

使用 +-= 来添加、移除或设置权限。

bash
chmod u+w filename      # 给所有者添加写权限
chmod o-r filename      # 移除其他用户的读权限
chmod g+w file.txt      # 为 file.txt 的所属组增加写权限
chmod o-rwx myscript.sh # 删除其他人对 myscript.sh 的所有权限
chmod u=rw,go= mydir/   # 将 mydir 的所有者权限改为 rw,所属组和其他人无任何权限
chmod a+x myscript.sh   # 为所有用户增加 myscript.sh 的执行权限,等同于 chmod +x myscript.sh

数字方式

八进制模式将权限表示为一个三位数,每一位代表一个权限组。每位数字可以是 0 到 7 之间的一个数,表示该组的权限。

  • 4: 读(r)
  • 2: 写(w)
  • 1: 执行(x)
bash
chmod 754 filename  # 设置所有者读、写、执行权限(7),组读、执行权限(5),其他用户读权限(4), 即 rwxr-xr--
chmod 755 filename  # 设置权限为 rwxr-xr-x
chmod 644 filename  # 设置权限为 rw-r--r--
chmod 644 file.txt    # 设置权限为 rw-r--r--
chmod 755 myscript.sh # 设置权限为 rwxr-xr-x
chmod -R 700 mydir/   # 设置 mydir/ 目录及其下所有文件权限为 rwx------

特殊权限

  • Setuid (SUID): 当设置在可执行文件上时,执行该文件的用户会临时获得文件所有者的权限。

    bash
    chmod u+s filename  # 设置 SUID
  • Setgid (SGID): 类似 SUID,但作用在组上。如果在目录上设置,目录下新创建的文件或目录会继承该目录的组权限。

    bash
    chmod g+s directory_name  # 设置 SGID
  • Sticky Bit: 主要用于目录,设置后,只有文件的所有者或者根用户才能删除该目录下的文件。

    bash
    chmod +t directory_name  # 设置 Sticky Bit

修改文件的所有者和组

  • chown(change owner)命令用于改变文件的所有者。

    bash
    chown new_owner filename
    chown new_owner:new_group filename
    
    chown [选项] [所有者][:[组]] 文件
  • chgrp(change group)命令用于改变文件的所属组。

    bash
    chgrp new_group filename
bash
chown john file.txt       # 将 file.txt 的所有者改为 john
chown :admins myscript.sh # 将 myscript.sh 的所属组改为 admins
chown -R john:devs mydir/ # 将 mydir/ 及其下所有文件的所有者改为 john,组改为 devs

ls -lah 查看文件(夹)信息

  • -l 选项表示以长格式(long format)列出文件信息。
  • -a 选项表示列出所有文件,包括以 . 开头的隐藏文件。默认情况下,ls 不会显示隐藏文件。
  • -h 选项表示以人类可读的格式显示文件大小。默认情况下,文件大小以字节为单位显示,使用 -h 选项后,文件大小会以更易读的单位显示,如 KB、MB、GB 等。

-l-a-h 选项组合使用时,ls -lah 命令会列出当前目录下的所有文件和文件夹(包括隐藏文件),并以长格式显示详细信息,同时文件大小以人类可读的格式显示。

bash
  ~ ls -lah /
# 格式为:
# 文件类型和权限 硬链接数 文件所有者 文件所属组 文件大小 最后修改时间 文件名
total 76K
dr-xr-xr-x.  20 root root 4.0K Sep  6 20:16 .
dr-xr-xr-x.  20 root root 4.0K Sep  6 20:16 ..
dr-xr-xr-x.   2 root root 4.0K Jun 25 22:23 afs
-rw-r--r--    1 root root    0 Jul 23 09:11 .autorelabel
lrwxrwxrwx    1 root root    7 Jun 25 22:23 bin -> usr/bin
dr-xr-xr-x.   5 root root 4.0K Jul 23 11:25 boot
drwxr-xr-x    2 root root 4.0K Feb  9  2022 data
drwxr-xr-x   19 root root 3.1K Jun 25 22:23 dev
drwxr-xr-x.  93 root root 4.0K Jul 31 16:07 etc
drwxr-xr-x.   3 root root 4.0K Jun 25 22:23 home
lrwxrwxrwx    1 root root    7 Jun 25 22:23 lib -> usr/lib
lrwxrwxrwx    1 root root    9 Jun 25 22:23 lib64 -> usr/lib64
drwx------.   2 root root  16K Jan 20  2022 lost+found
drwxr-xr-x.   2 root root 4.0K Jun 25 22:23 media
drwxr-xr-x.   2 root root 4.0K Jun 25 22:23 mnt
drwxr-xr-x.   2 root root 4.0K Jun 25 22:23 opt
dr-xr-xr-x  199 root root    0 Jul 23 09:11 proc
dr-xr-x---.   9 root root 4.0K Sep  6 20:16 root
drwxr-xr-x   28 root root 1000 Jul 23 12:19 run
lrwxrwxrwx    1 root root    8 Jun 25 22:23 sbin -> usr/sbin
drwxr-xr-x.   2 root root 4.0K Jun 25 22:23 srv
dr-xr-xr-x   13 root root    0 Jul 23 11:22 sys
drwxrwxrwt.   7 root root 4.0K Sep  6 20:16 tmp
drwxr-xr-x.  12 root root 4.0K Jul 23 11:22 usr
drwxr-xr-x.  19 root root 4.0K Jul 23 11:22 var

长格式提供了以下详细信息:

  1. 文件类型和权限
    • 第一个字符表示文件类型:
      • - 表示普通文件
      • d 表示目录
      • l 表示符号链接
      • c 表示字符设备文件
      • b 表示块设备文件
      • p 表示命名管道
      • s 表示套接字
    • 接下来的 9 个字符表示文件权限:
      • 每 3 个字符一组,分别表示文件所有者、文件所属组和其他用户的权限。
      • 权限字符包括 r(读)、w(写)、x(执行)。
  2. 硬链接数:表示指向该文件的硬链接数量。
  3. 文件所有者:文件或目录的所有者用户名。
  4. 文件所属组:文件或目录所属的用户组名。
  5. 文件大小:文件的大小,以字节为单位。
  6. 最后修改时间:文件或目录的最后修改时间。
  7. 文件名:文件或目录的名称。若是软链接,则文件名会直接展示链接到的源文件。

stat 查看文件(夹)信息

stat 命令的输出通常包含以下几个部分:

属性说明
File文件的完整路径
Size文件的大小,以字节为单位
Blocks文件占用的块数
IO Block文件系统的 IO 块大小
File type文件类型
Device文件所在的设备号
Inode文件的 inode 号
Links文件的硬链接数
Access文件的访问权限
Uid文件所有者的用户 ID 和用户名
Gid文件所属组的用户组 ID 和组名
Access time文件的最后访问时间
Modify time文件内容的最后修改时间
Change time文件元数据的最后修改时间
bash
  ~ stat /.autorelabel
  File: /.autorelabel
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fd01h/64769d    Inode: 724         Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-07-23 09:11:54.500000000 +0800
Modify: 2024-07-23 09:11:54.500000000 +0800
Change: 2024-07-23 09:11:54.500000000 +0800
 Birth: 2024-07-23 09:11:54.499000000 +0800
  1. File:文件的完整路径。
    • /.autorelabel:文件名及其路径。
  2. Size:文件的大小。
    • 0:文件大小为 0 字节,表示这是一个空文件。
  3. Blocks:文件占用的块数。
    • 0:文件占用了 0 个块。
  4. IO Block:文件系统的 IO 块大小。
    • 4096:文件系统的 IO 块大小为 4096 字节。
  5. File type:文件类型。
    • regular empty file:这是一个普通空文件。
  6. Device:文件所在的设备号。
    • fd01h/64769d:设备号为 fd01(十六进制)或 64769(十进制)。
  7. Inode:文件的 inode 号。
    • 724:文件的 inode 号为 724。
  8. Links:文件的硬链接数。
    • 1:文件有 1 个硬链接。
  9. Access:文件的访问权限。
    • 0644:文件的权限为 0644,表示所有者有读写权限,组用户和其他用户只有读权限。
    • -rw-r--r--:文件权限的符号表示。
  10. Uid:文件所有者的用户 ID 和用户名。
    • 0:用户 ID 为 0。
    • root:用户名为 root
  11. Gid:文件所属组的用户组 ID 和组名。
    • 0:用户组 ID 为 0。
    • root:用户组名为 root
  12. Access time:文件的最后访问时间。
    • 2024-07-23 09:11:54.500000000 +0800:文件的最后访问时间为 2024 年 7 月 23 日 09:11:54,时区为 +0800。
  13. Modify time:文件内容的最后修改时间。
    • 2024-07-23 09:11:54.500000000 +0800:文件内容的最后修改时间为 2024 年 7 月 23 日 09:11:54,时区为 +0800。
  14. Change time:文件元数据(状态)的最后修改时间。
    • 2024-07-23 09:11:54.500000000 +0800:文件元数据的最后修改时间为 2024 年 7 月 23 日 09:11:54,时区为 +0800。
  15. Birth:文件的创建时间。
    • 2024-07-23 09:11:54.499000000 +0800:文件的创建时间为 2024 年 7 月 23 日 09:11:54,时区为 +0800。

通过 stat /.autorelabel 命令的输出,我们可以了解到以下信息:

  • /.autorelabel 是一个普通空文件,大小为 0 字节,占用了 0 个块。
  • 文件系统的 IO 块大小为 4096 字节。
  • 文件所在的设备号为 fd01(十六进制)或 64769(十进制)。
  • 文件的 inode 号为 724,硬链接数为 1。
  • 文件的访问权限为 0644,所有者和所属组均为 root
  • 文件的最后访问时间、最后修改时间和元数据修改时间均为 2024 年 7 月 23 日 09:11:54,时区为 +0800。
  • 文件的创建时间为 2024 年 7 月 23 日 09:11:54,时区为 +0800。
bash
  ~ stat sed_test.txt # 查看文件信息
  File: sed_test.txt
  Size: 275             Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 394782      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-08-09 04:26:43.355201176 +0800
Modify: 2024-08-09 04:26:35.937167660 +0800
Change: 2024-08-09 04:26:35.937167660 +0800
 Birth: 2024-08-09 04:26:35.937167660 +0800
  ~ touch sed_test.txt # 访问时间、修改时间和元数据修改时间发生变化
  File: sed_test.txt
  Size: 275             Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 394782      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-09-06 20:27:52.214290936 +0800
Modify: 2024-09-06 20:27:51.886289365 +0800
Change: 2024-09-06 20:27:51.886289365 +0800
 Birth: 2024-08-09 04:26:35.937167660 +0800
  ~ chmod 655 sed_test.txt # 元数据修改时间发生变化
  ~ stat sed_test.txt
  File: sed_test.txt
  Size: 275             Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 394782      Links: 1
Access: (0655/-rw-r-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-09-06 20:27:52.214290936 +0800
Modify: 2024-09-06 20:27:51.886289365 +0800
Change: 2024-09-06 20:28:22.287434849 +0800
 Birth: 2024-08-09 04:26:35.937167660 +0800
  ~ head -n 3 sed_test.txt # 访问时间发生变化
Line 1: Hello, World!
Line 2: sed is a stream editor.
Line 3: This is a simple text file.
  ~ stat sed_test.txt
  File: sed_test.txt
  Size: 275             Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 394782      Links: 1
Access: (0655/-rw-r-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-09-06 20:28:50.837571480 +0800
Modify: 2024-09-06 20:27:51.886289365 +0800
Change: 2024-09-06 20:28:22.287434849 +0800
 Birth: 2024-08-09 04:26:35.937167660 +0800
  ~ sed -i '1i/a' sed_test.txt # 访问时间、修改时间和元数据修改时间发生变化
  ~ stat sed_test.txt
  File: sed_test.txt
  Size: 278             Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 394781      Links: 1
Access: (0655/-rw-r-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-09-06 20:29:59.385899532 +0800
Modify: 2024-09-06 20:29:59.385899532 +0800
Change: 2024-09-06 20:29:59.385899532 +0800
 Birth: 2024-09-06 20:29:59.385899532 +0800

lsattr 和 chattr

  • 在 Linux 系统中,lsattrchattr 是用于查看和修改文件或目录的扩展属性的命令。这些扩展属性提供了一些额外的功能,例如防止文件被删除或修改。
  • attrattribute 的缩写,表示属性。
  • lsattr 命令用于列出文件或目录的扩展属性,而 chattr 命令用于修改文件或目录的扩展属性。
bash
  ~ yum provides lsattr # 查看 lsattr 命令的安装包
e2fsprogs-1.46.2-2.el9.x86_64 : Utilities for managing ext2, ext3, and ext4 file systems
Repo        : baseos
Matched from:
Filename    : /usr/bin/lsattr

  ~ sudo yum install e2fsprogs # 安装 e2fsprogs 包
Package e2fsprogs-1.46.5-5.el9.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!

lsattr 命令

lsattr 命令用于列出文件或目录的扩展属性。

bash
lsattr [选项] [文件或目录]
  • -a:显示所有文件,包括以 . 开头的隐藏文件。
  • -d:如果指定的是目录,则显示目录本身的属性,而不是目录中的文件。
  • -R:递归显示目录及其子目录中的文件属性。
  • -v:显示文件的版本(如果存在)。
bash
lsattr file.txt
----i---------e--- file.txt

chattr 命令

chattr 命令用于修改文件或目录的扩展属性。

bash
chattr [选项] [属性] 文件或目录
  • 常用选项

    • +:添加指定的属性。
    • -:移除指定的属性。
    • =:设置指定的属性,移除其他所有属性。
  • 常用属性

    • a:只能以追加模式打开文件,即只能追加内容,不能删除或修改已有内容。(append only)
    • i:使文件不可变,即不能删除、重命名、修改或链接。(immutable)
    • d:在执行 dump 命令时,不会备份该文件。(no dump)
    • e:表示文件使用扩展属性(extents)来映射磁盘上的块。(extent)
    • s:当文件被删除时,其数据块会被清零。(synchronized)
    • u:当文件被删除时,其内容会被保存,以便以后可以恢复。(undelete)
bash
chattr +i file.txt # 使 file.txt 不可变
chattr -i file.txt # 移除 file.txt 的不可变属性

# 防止文件被删除或修改
chattr +i important_file.txt # 使 important_file.txt 不可变,防止任何用户(包括 root)删除或修改该文件。

# 允许文件只能追加内容
chattr +a logfile.log # 使 logfile.log 只能以追加模式打开,防止覆盖或删除已有内容。

注意事项

  • chattr 命令需要 root 权限才能执行。
  • 某些文件系统(如 ext2/ext3/ext4)支持这些扩展属性,而其他文件系统可能不支持。
  • 使用 chattr 修改文件属性时要小心,因为某些属性(如 i)可能会导致文件无法被删除或修改,除非移除该属性。

通过 lsattrchattr 命令,管理员可以更好地控制文件和目录的行为,特别是在需要保护重要数据时。

bash
  ~ lsattr data.txt # 查看 data.txt 文件属性
--------------e------- data.txt
  ~ chattr +i data.txt # 给 data.txt 文件添加不可变属性 i
  ~ lsattr data.txt # 查看 data.txt 文件属性
----i---------e------- data.txt
  ~ rm -f data.txt # 删除 data.txt 文件,提示操作不允许
rm: cannot remove 'data.txt': Operation not permitted
  ~ sudo rm -f data.txt # 使用 sudo 权限删除 data.txt 文件,提示操作不允许
rm: cannot remove 'data.txt': Operation not permitted
  ~ chattr -i data.txt # 移除 data.txt 文件的不可变属性 i
  ~ lsattr data.txt # 查看 data.txt 文件属性
--------------e------- data.txt
  ~ rm -f data.txt # 删除 data.txt 文件
  ~ ls data.txt # 查看 data.txt 文件,文件不存在
ls: cannot access 'data.txt': No such file or directory
bash
  ~ lsattr lol.info # 查看 lol.info 文件属性
--------------e------- lol.info
  ~ chattr +a lol.info # 给 lol.info 文件添加只能追加内容属性 a
  ~ lsattr lol.info
-----a--------e------- lol.info
  ~ vim lol.info # 编辑 lol.info 文件,提示操作不允许

"lol.info" E212: Can't open file for writing
Press ENTER or type command to continue

➜  ~ sed -i '2a\newline' lol.info # 在 lol.info 文件的第二行添加 newline 内容,提示操作不允许
sed: cannot rename ./sedPSBaPZ: Operation not permitted
➜  ~ echo newline >> lol.info # 在 lol.info 文件的末尾添加 newline 内容,可以正常追加
➜  ~ tail -3 lol.info
name: 琴女
city: 诺克萨斯
newline