嵌入式Linux:文件访问权限
在 Linux 中,文件访问权限决定了哪些用户和用户组可以读取、写入或执行文件。这些权限通过文件系统中的元数据来定义,并且可以使用多种工具进行查看和更改。
拓展学习:https://handsome-man.blog.csdn.net/article/details/140277433
https://handsome-man.blog.csdn.net/article/details/139511962
每个文件和目录都有三个不同的权限级别:
- 所有者(Owner):文件或目录的创建者。
- 用户组(Group):与文件或目录相关联的用户组。
- 其他用户(Others):系统中的其他所有用户。
每个级别都有三个权限:
- 读取(Read, r):允许读取文件内容或列出目录内容。
- 写入(Write, w):允许修改文件内容或创建、删除目录中的文件。
- 执行(Execute, x):允许执行文件(对于目录,允许进入该目录)。
1、查看文件权限
使用 ls -l 命令可以查看文件和目录的权限。例如:
$ ls -l
-rw-r--r-- 1 user group 1234 Jan 1 12:34 example.txt

输出的第一列包含 10 个字符,代表文件类型和权限:
- 第一个字符:文件类型(
-表示普通文件,d表示目录,l表示符号链接等)。 - 后面九个字符:每组三个字符,分别表示所有者、组和其他用户的权限。
在这个示例中,-rw-r--r-- 表示:
- 所有者:
rw-(读和写) - 用户组:
r--(只读) - 其他用户:
r--(只读)
2、修改文件权限
使用 chmod 命令可以更改文件或目录的权限。有两种方式:符号表示法和八进制表示法。
2.1、符号表示法
符号表示法使用 +、- 和 = 操作符来添加、移除或设置权限。
示例如下:
# 为所有者添加执行权限
$ chmod u+x example.txt
# 为用户组添加写权限
$ chmod g+w example.txt
# 为其他用户移除读权限
$ chmod o-r example.txt
# 为所有用户设置读取权限
$ chmod a=r example.txt
2.2、八进制表示法
八进制表示法使用三个八进制数字来表示所有者、组和其他用户的权限。
每个权限有一个相应的值:
- 读取(r):4
- 写入(w):2
- 执行(x):1
示例如下:
# 设置所有者读写执行,组读执行,其他用户只读
$ chmod 754 example.txt
# 设置所有用户读写执行权限
$ chmod 777 example.txt
3、access函数
access 函数用于检查调用进程是否有权限访问指定的文件或目录。它可以用来判断一个文件是否存在,以及检查读、写、执行权限。
函数原型如下:
#include <unistd.h>
int access(const char *pathname, int mode);
参数说明
pathname:要检查的文件或目录的路径。mode:要检查的权限,可以是以下常量的组合:F_OK:检查文件是否存在。R_OK:检查文件是否可读。W_OK:检查文件是否可写。X_OK:检查文件是否可执行。
返回值
- 如果调用进程具有指定的访问权限,则返回 0。
- 如果调用进程不具有指定的访问权限,或者出错,则返回 -1,并设置
errno以指示错误。
以下是一个示例程序,它使用 access 函数检查文件的各种访问权限。
#include <stdio.h>
#include <unistd.h>
void check_access(const char *filepath) {
// 检查文件是否存在
if (access(filepath, F_OK) == 0) {
printf("File %s exists.\n", filepath);
} else {
printf("File %s does not exist.\n", filepath);
return;
}
// 检查文件是否可读
if (access(filepath, R_OK) == 0) {
printf("File %s is readable.\n", filepath);
} else {
printf("File %s is not readable.\n", filepath);
}
// 检查文件是否可写
if (access(filepath, W_OK) == 0) {
printf("File %s is writable.\n", filepath);
} else {
printf("File %s is not writable.\n", filepath);
}
// 检查文件是否可执行
if (access(filepath, X_OK) == 0) {
printf("File %s is executable.\n", filepath);
} else {
printf("File %s is not executable.\n", filepath);
}
}
int main() {
const char *filepath = "example.txt";
check_access(filepath);
return 0;
}
注意事项
access函数是基于真实用户 ID 和组 ID 进行检查的,而不是有效用户 ID 和组 ID。- 由于文件权限可能会在检查后立即变化,因此使用
access来进行安全性检查时要格外小心。 - 尽量避免在实际操作前仅用
access检查权限,而应该直接处理文件操作,并检查返回值。
4、chmod函数
chmod 函数用于更改文件的访问权限。它可以修改文件的读、写、执行权限。
函数原型如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int chmod(const char *pathname, mode_t mode);
参数说明
pathname:要更改权限的文件或目录的路径。mode:新的文件模式(权限),由一些按位或(OR)组合的位组成。常用的模式有:S_IRUSR:文件所有者具有读权限。S_IWUSR:文件所有者具有写权限。S_IXUSR:文件所有者具有执行权限。S_IRGRP:文件组用户具有读权限。S_IWGRP:文件组用户具有写权限。S_IXGRP:文件组用户具有执行权限。S_IROTH:其他用户具有读权限。S_IWOTH:其他用户具有写权限。S_IXOTH:其他用户具有执行权限。
这些常量可以通过按位或(|)组合在一起,形成一个完整的模式。
返回值
- 成功时返回 0。
- 失败时返回 -1,并设置
errno以指示错误。
以下是一个示例程序,演示如何使用 chmod 函数更改文件的访问权限。
#include <stdio.h>
#include <sys/stat.h>
int main() {
const char *filepath = "example.txt";
// 更改文件权限为所有者可读可写,组用户和其他用户只读
if (chmod(filepath, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == 0) {
printf("Changed permissions successfully.\n");
} else {
perror("chmod");
}
return 0;
}
在这个示例中,chmod 函数被调用以更改文件 example.txt 的权限。新权限设置为:
- 文件所有者具有读(
S_IRUSR)和写(S_IWUSR)权限。 - 文件组用户具有读(
S_IRGRP)权限。 - 其他用户具有读(
S_IROTH)权限。
文件权限是通过模式位的组合来指定的。常用的模式位有:
S_IRUSR(0400):文件所有者读权限。S_IWUSR(0200):文件所有者写权限。S_IXUSR(0100):文件所有者执行权限。S_IRGRP(0040):文件组用户读权限。S_IWGRP(0020):文件组用户写权限。S_IXGRP(0010):文件组用户执行权限。S_IROTH(0004):其他用户读权限。S_IWOTH(0002):其他用户写权限。S_IXOTH(0001):其他用户执行权限。
例如,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH 组合了所有者的读写权限和组用户与其他用户的读权限,结果权限为 0644。
如果 chmod 成功,则返回 0,否则返回 -1,并在标准错误流中输出错误信息。使用 perror 函数打印错误原因。
chmod 函数是一个强大的工具,可以方便地更改文件的访问权限。正确使用它可以提高系统的安全性和文件管理的效率。在使用时,要注意权限的合理设置,以防止权限过高或过低带来的安全隐患。常见错误如下:
EACCES:权限不足,无法更改文件权限。EPERM:操作不被允许,例如试图更改系统文件的权限。ENOENT:指定的文件不存在。ENOTDIR:指定的路径中有不是目录的部分。
作者:不脱发的程序猿。来源:CSDN 原文(CC BY-SA 4.0)。



