Linux编程入门(7)-目录与文件的特殊属性

回顾

前面两篇文章学习了目录和文件的相关属性:

Linux编程入门(5)-读取目录(ls 初步实现)

Linux编程入门(6)-读取目录与文件的属性(ls 进阶)

文件属性信息结构体 struct stat 定义如下:

struct stat 
{
  dev_t     st_dev;         /* ID of device containing file */
  ino_t     st_ino;         /* i节点号 */
  mode_t    st_mode;        /* 文件类型和许可权限 */
  nlink_t   st_nlink;       /* 文件链接数 */
  uid_t     st_uid;         /* 文件所有者用户ID */
  gid_t     st_gid;         /* 所属组的ID */
  dev_t     st_rdev;        /* Device ID (if special file) */
  off_t     st_size;        /* 文件所占的字节数 */
  blksize_t st_blksize;     /* Block size for filesystem I/O */
  blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

  struct timespec st_atim;  /* 文件最后修改时间 */
  struct timespec st_mtim;  /* 文件最后访问时间 */
  struct timespec st_ctim;  /* 文件属性最后修改时间 */

	/* 向后兼容 */
  #define st_atime st_atim.tv_sec  /* 文件最后修改时间 */
  #define st_mtime st_mtim.tv_sec  /* 文件最后访问时间 */
  #define st_ctime st_ctim.tv_sec  /* 文件属性最后修改时间 */
};

文件类型和许可权限存储在 st_mode 中,字段所含位信息的布局情况如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1XGGAP7y-1639583551669)(M:\document\03.Linux\02.Linux编程入门\07.Linux编程入门(7)]-目录与文件的特殊属性\image-20211122191803332.png)

文件类型和操作权限在上一篇文章中做了介绍。但是其中有三个特殊位没有进行讲解,分别是

  • Set-User-ID(U)
  • Set-Group-ID(G)
  • Sticky(T)

我们分别进行介绍。

Set-User-ID 位

这个位的作用是,告诉内核,运行某个程序的时候,认为是由文件所有者在运行这个程序。即,set-user-ID 会将执行某个程序的有效用户 ID 置为可执行文件的用户 ID(属主)。从而获得常规情况下并不具备的权限。

例如,如果一个可执行程序文件的属主为 root,且此文件设置了 set-user-ID 权限位,那么当试运行该程序时,进程会取得超级用户权限。

Linux 系统中经常使用 set-user-ID 的程序包括:

  • passwd,用于更改用户密码
  • mount 和 unmount,用于加载和卸载文件系统
  • su,允许用户以另一个用户身份运行 shell

Set-Group-ID 位

与 set-user-ID 作用类似,这个位用来设置程序运行时所属组的。如果某个程序文件设置了 set-group-ID ,那么该程序运行时,就好像它被属组中的某一个用户运行一样。

set-group-ID 给程序某一个组的访问权限

Linux 系统中使用 set-group-ID 的程序例子之一:wall,用来向 tty 组下辖的所有终端写入一条消息。

Sticky 位

Sticky 位对于文件和目录有着不同的用途。

对于文件

在 Unix 的早期版本中,这个位被称为粘着位(sticky bit)。提供 sticky 位的目的在于让常用应用程序运行速度更快。

早期的系统经常在有限的内存空间中同时运行很多程序,它使用到交换(swap)技术。在某个时刻如果有程序没运行,内核会把它临时存放到硬盘上一个叫交换空间的分区中,空出来的内存可以给其他程序使用。

若对某程序文件设置了 sticky 位,则首次执行程序时,系统会将其文本拷贝并保存在交换区中,即“粘”(sticky)在交换区内,因此用够提高后续执行的加载速度。

在交换空间装载程序要比从普通的硬盘空间快,在交换空间上的文件是不分块的;而在非交换空间的硬盘上,程序可能被分成好几块,分别放在多个地方,加载的时候会从磁盘的多个地方读取程序数据。

较新的 Unix(Linux)系统大多数都配置了虚拟存储系统以及快速文件系统,交换技术不再那么重要了。虚拟内存可以以更小的单位,如页(page),进行交换。

对于目录

新的系统扩展了粘着位的使用范围,允许对目录设置粘着位。此时,sticky 位起到限制删除位的作用。

如果对某个目录设置了 sticky 位,只有对该目录具有写权限的用户且满足下列条件之一,才能删除或重命名该目录下的文件:

  • 拥有此文件
  • 拥有此目录
  • 超级用户

利用这个机制,可以创建为多个用户共享的一个目录,各个用户在其下创建或删除属于属于自己的文件,但不能删除隶属于其他用户的文件。

例如,目录 /tmp 设置了 sticky 位。任何用户都可以在这里创建或删除文件,目录里的文件只能被创建者(拥有者)删除或重命名。

查看特殊属性信息

通过命令 ls -l 可以查看文件的属性信息。每个文件由 12 位的文件属性,但是 ls 只用 9 个字符来表示,那如表示 3 个特殊位呢?

文件的权限位可通过 chmod 命令进行设置。

set-user-ID 位

文件设置了该位,则会在文件用户执行权限字段(x)上进行显示:如果执行权限打开,则对应位置显示小写字母 “s”,否则,显示大写字母 “S”。例如

$ ls -l
-rw-rw-r-- 1 user user 0 11月 23 01:13 test

$ chmod u+s test 
$ ls -l
-rwSrw-r-- 1 user user 0 11月 23 01:13 test

$ chmod u+x test 
$ ls -l
-rwsrw-r-- 1 user user 0 11月 23 01:13 test

set-group-ID位

文件设置了该位,则会在文件数组执行权限字段(x)上进行显示:如果执行权限打开,则对应位置显示小写字母 “s”,否则,显示大写字母 “S”。例如

$ ls -l
-rw-rw-r-- 1 user user 0 11月 23 01:13 test

$ chmod g+s test 
$ ls -l
-rw-rwSr-- 1 user user 0 11月 23 01:13 test

$ chmod g+x test 
$ ls -l
-rw-rwsr-- 1 user user 0 11月 23 01:13 test

Sticky

文件设置了该位,则会在文件其他用户执行权限字段(x)上进行显示:如果执行权限打开,则对应位置显示小写字母 “t”,否则,显示大写字母 “T”。例如

$ ls -l
-rw-rw-r-- 1 user user 0 11月 23 01:13 test

$ chmod +t test 
$ ls -l
-rw-rw-r-T 1 user user 0 11月 23 01:13 test

$ chmod o+x test 
$ ls -l
-rw-rw-r-t 1 user user 0 11月 23 01:13 test

小结

本文介绍了文件属性中的三个特殊位。建议,这几个特殊位不要轻易使用,如果设计欠佳可能会造成安全感隐患。

至此,文件和目录的属性相关基础内容学习完毕。后面将开启新的内容学习。

——————————————————————————————

关注公众号【一起学习嵌入式】,后台回复 “ linux ” 获取Linux经典书籍。
Linux编程入门(7)-目录与文件的特殊属性

上一篇:【笔记】生成树


下一篇:题解 P7706 「Wdsr-2.7」文文的摄影布置