chmod系统调用及示例

我们继续学习 Linux 系统编程中的重要函数。这次我们介绍 chmod 函数,它用于改变文件的访问权限。

data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">

chmod 函数简介

1. 函数介绍

chmod 是一个 Linux 系统调用,用于改变文件或目录的访问权限(也称为文件模式位)。这些权限决定了哪些用户可以读取、写入或执行文件。

文件权限是 Unix/Linux 系统安全模型的基础。每个文件都有三组权限位:所有者(user)、所属组(group)和其他用户(others)。每组权限又包含三种基本权限:读(read, r)、写(write, w)和执行(execute, x)。

通过 chmod,具有适当权限的用户(通常是文件所有者或 root)可以调整这些权限,以控制对文件的访问。例如,一个用户可能希望保护一个私密文件,使其只能被自己读取;或者希望让一个脚本文件对所有用户都可执行。

2. 函数原型

1
2
3
4
#include <sys/stat.h> // 必需

int chmod(const char *pathname, mode_t mode);

3. 功能

  • 改变文件权限: 将由 pathname 指定的文件或目录的访问权限设置为 mode 参数指定的值。

  • 设置绝对权限: mode 参数通常是一个八进制数(如 0644, 0755)或通过位运算组合的符号常量(如 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)。

4. 参数

  • const char *pathname: 指向一个以空字符 (\0) 结尾的字符串,该字符串包含了要更改权限的文件或目录的路径名。这可以是相对路径或绝对路径。

mode_t mode: 指定新的文件权限。这个参数可以有两种表示方式:

八进制表示法:

  • 最常见的形式,如 0644, 0755, 0600。

  • 第一个数字 0 表示这是一个八进制数。

  • 接下来的三位数字分别代表所有者(user)、组(group)、其他用户(others)的权限。

每一位的值是读(4)、写(2)、执行(1)的组合:

  • 7 (4+2+1) = 读+写+执行 (rwx)

  • 6 (4+2) = 读+写 (rw-)

  • 5 (4+1) = 读+执行 (r-x)

  • 4 (4) = 只读 (r–)

  • 0 = 无权限 (—)

例如:

  • 0644 表示所有者:读写 (6),组和其他用户:只读 (4)。常用于普通文件。

  • 0755 表示所有者:读写执行 (7),组和其他用户:读执行 (5)。常用于可执行文件或目录。

  • 0600 表示所有者:读写 (6),组和其他用户:无权限 (0)。常用于私密文件。

符号常量表示法:

  • 使用 <sys/stat.h> 中定义的宏进行位运算组合。

用户类别:

  • S_IRWXU: 所有者的读、写、执行权限

  • S_IRUSR: 所有者的读权限

  • S_IWUSR: 所有者的写权限

  • S_IXUSR: 所有者的执行权限

组类别:

  • S_IRWXG: 组的读、写、执行权限

  • S_IRGRP: 组的读权限

  • S_IWGRP: 组的写权限

  • S_IXGRP: 组的执行权限

其他用户类别:

  • S_IRWXO: 其他用户的读、写、执行权限

  • S_IROTH: 其他用户的读权限

  • S_IWOTH: 其他用户的写权限

  • S_IXOTH: 其他用户的执行权限

特殊位:

  • S_ISUID: 设置用户ID位 (set-user-ID)

  • S_ISGID: 设置组ID位 (set-group-ID)

  • S_ISVTX: 粘滞位 (sticky bit)

例如:

  • S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH 等价于 0644。

  • S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH 等价于 0755。

5. 返回值

  • 成功时: 返回 0。

失败时:

返回 -1,并设置全局变量 errno 来指示具体的错误原因:

  • EACCES: 搜索路径名中的某个目录被拒绝。

  • EROFS: 路径名存在于只读文件系统上。

  • EIO: 执行 I/O 错误。

  • ELOOP: 解析 pathname 时遇到符号链接环。

  • ENAMETOOLONG: 路径名过长。

  • ENOENT: 文件不存在。

  • ENOMEM: 路径名无法分配内存。

  • ENOTDIR: 路径名前缀不是一个目录。

  • EPERM: 操作不被文件系统或操作系统允许。例如,尝试在某些文件系统上设置 set-group-ID 位。

  • EFAULT: pathname 指针指向进程地址空间之外。

  • EINVAL: mode 参数无效。

6. 相似函数,或关联函数

  • fchmod(int fd, mode_t mode): 与 chmod 功能相同,但通过已打开的文件描述符而不是路径名来指定文件。这可以避免路径解析。

  • fchmodat(int dirfd, const char *pathname, mode_t mode, int flags): 更现代的函数,允许使用相对路径(相对于 dirfd 描述符对应的目录)并提供额外的标志。

  • umask(mode_t mask): 设置进程的文件权限掩码,它会影响后续创建的文件的默认权限。

  • stat, lstat, fstat: 这些函数可以用来获取文件的当前权限,而不是设置它们。

7. 示例代码

示例 1:基本的权限更改

这个例子演示了如何使用 chmod 来更改文件的权限,包括八进制和符号常量两种方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <sys/stat.h>  // chmod, stat, struct stat
#include <stdio.h> // perror, printf
#include <stdlib.h> // exit
#include <errno.h> // errno
#include <string.h> // strerror

// 辅助函数:将 mode_t 转换为可读的权限字符串
void print_permissions(mode_t mode) {
char perms&#91;11];
// 初始化字符数组
strcpy(perms, "----------");

// 用户权限
if (mode & S_IRUSR) perms&#91;1] = 'r';
if (mode & S_IWUSR) perms&#91;2] = 'w';
if (mode & S_IXUSR) perms&#91;3] = 'x';

// 组权限
if (mode & S_IRGRP) perms&#91;4] = 'r';
if (mode & S_IWGRP) perms&#91;5] = 'w';
if (mode & S_IXGRP) perms&#91;6] = 'x';

// 其他用户权限
if (mode & S_IROTH) perms&#91;7] = 'r';
if (mode & S_IWOTH) perms&#91;8] = 'w';
if (mode & S_IXOTH) perms&#91;9] = 'x';

// 特殊位
if (mode & S_ISUID) perms&#91;3] = (perms&#91;3] == 'x') ? 's' : 'S';
if (mode & S_ISGID) perms&#91;6] = (perms&#91;6] == 'x') ? 's' : 'S';
if (mode & S_ISVTX) perms&#91;9] = (perms&#91;9] == 'x') ? 't' : 'T';

printf("%s", perms);
}

// 辅助函数:打印文件的详细信息
void print_file_info(const char *pathname) {
struct stat sb;
if (stat(pathname, &sb) == -1) {
perror("stat");
return;
}

printf("文件 '%s' 的信息:\n", pathname);
printf(" Inode: %ld\n", sb.st_ino);
printf(" 权限: ", pathname);
print_permissions(sb.st_mode);
printf(" (八进制: %o)\n", sb.st_mode & 0777);
printf(" 大小: %ld 字节\n", sb.st_size);
}

int main(int argc, char *argv&#91;]) {
if (argc != 3) {
fprintf(stderr, "用法: %s <文件路径> <新权限>\n", argv&#91;0]);
fprintf(stderr, " 权限可以是八进制 (如 0644) 或符号 (如 u+r)\n");
fprintf(stderr, " 示例: %s myfile.txt 0644\n", argv&#91;0]);
fprintf(stderr, " %s script.sh 0755\n", argv&#91;0]);
exit(EXIT_FAILURE);
}

const char *pathname = argv&#91;1];
const char *mode_str = argv&#91;2];

printf("准备更改文件 '%s' 的权限\n", pathname);

// 打印更改前的信息
print_file_info(pathname);

// 解析权限模式
mode_t new_mode;
char *endptr;

// 尝试解析为八进制数
new_mode = (mode_t) strtol(mode_str, &endptr, 8);
if (*endptr != '\0') {
fprintf(stderr, "错误: 不支持的权限格式 '%s'。请使用八进制数(如 0644)。\n", mode_str);
exit(EXIT_FAILURE);
}

printf("\n新的权限模式: ");
print_permissions(new_mode);
printf(" (八进制: %o)\n", new_mode);

// 执行 chmod 操作
if (chmod(pathname, new_mode) == -1) {
perror("chmod 失败");
exit(EXIT_FAILURE);
}

printf("\nchmod 操作成功!\n");

// 打印更改后的信息
print_file_info(pathname);

return 0;
}

代码解释:

定义了两个辅助函数:

  • print_permissions: 将 mode_t 类型的权限值转换为人类可读的字符串(如 -rw-r–r–)。

  • print_file_info: 使用 stat 获取并打印文件的详细信息,包括权限。

main 函数接受文件路径和权限字符串作为参数。

它使用 strtol 将权限字符串解析为八进制数。

调用 print_file_info 显示更改前的状态。

调用 chmod(pathname, new_mode) 执行权限更改。

如果成功,再次调用 print_file_info 显示更改后的状态。

示例 2:批量权限管理

这个例子模拟了一个简单的批量权限管理工具,可以同时更改多个文件的权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#define _GNU_SOURCE
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <fnmatch.h> // 用于模式匹配

// 递归更改目录下匹配模式的文件权限
int change_permissions_recursive(const char *dir_path, const char *pattern, mode_t mode, int verbose) {
DIR *dir;
struct dirent *entry;
char full_path&#91;1024];
int changed_count = 0;
int error_count = 0;

dir = opendir(dir_path);
if (!dir) {
fprintf(stderr, "无法打开目录 '%s': %s\n", dir_path, strerror(errno));
return -1;
}

while ((entry = readdir(dir)) != NULL) {
// 跳过 . 和 ..
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}

// 构造完整路径
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name);

// 检查是否匹配模式
if (fnmatch(pattern, entry->d_name, 0) == 0) {
// 匹配,尝试更改权限
if (chmod(full_path, mode) == -1) {
fprintf(stderr, "警告: 无法更改 '%s' 的权限: %s\n", full_path, strerror(errno));
error_count++;
} else {
if (verbose) {
printf("已更改 '%s' 的权限\n", full_path);
}
changed_count++;
}
}

// 如果是目录,则递归处理
struct stat sb;
if (stat(full_path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
int sub_result = change_permissions_recursive(full_path, pattern, mode, verbose);
if (sub_result >= 0) {
changed_count += sub_result;
} else {
error_count++;
}
}
}

closedir(dir);

if (error_count > 0) {
return -1;
}
return changed_count;
}

// 打印权限更改的摘要
void print_mode_summary(mode_t mode) {
printf("权限设置为: ");
// 用户权限
printf((mode & S_IRUSR) ? "r" : "-");
printf((mode & S_IWUSR) ? "w" : "-");
printf((mode & S_IXUSR) ? "x" : "-");
// 组权限
printf((mode & S_IRGRP) ? "r" : "-");
printf((mode & S_IWGRP) ? "w" : "-");
printf((mode & S_IXGRP) ? "x" : "-");
// 其他用户权限
printf((mode & S_IROTH) ? "r" : "-");
printf((mode & S_IWOTH) ? "w" : "-");
printf((mode & S_IXOTH) ? "x" : "-");
printf(" (八进制: %04o)\n", mode);
}

int main(int argc, char *argv&#91;]) {
if (argc < 4) {
fprintf(stderr, "用法: %s <目录路径> <文件模式> <权限> &#91;-r] &#91;-v] &#91;-p pattern]\n", argv&#91;0]);
fprintf(stderr, " -r: 递归处理子目录\n");
fprintf(stderr, " -v: 详细输出\n");
fprintf(stderr, " -p pattern: 只处理匹配模式的文件 (支持通配符)\n");
fprintf(stderr, " 示例: %s /home/user *.txt 0644 -r -v\n", argv&#91;0]);
fprintf(stderr, " %s /var/log 0600 -p \"*.log\"\n", argv&#91;0]);
exit(EXIT_FAILURE);
}

const char *dir_path = argv&#91;1];
const char *pattern = argv&#91;2];
const char *mode_str = argv&#91;3];
int recursive = 0;
int verbose = 0;
const char *file_pattern = "*"; // 默认匹配所有文件

// 解析选项
for (int i = 4; i < argc; i++) {
if (strcmp(argv&#91;i], "-r") == 0) {
recursive = 1;
} else if (strcmp(argv&#91;i], "-v") == 0) {
verbose = 1;
} else if (strcmp(argv&#91;i], "-p") == 0 && i + 1 < argc) {
file_pattern = argv&#91;++i];
} else {
fprintf(stderr, "未知选项: %s\n", argv&#91;i]);
exit(EXIT_FAILURE);
}
}

// 解析权限模式
mode_t mode;
char *endptr;
mode = (mode_t) strtol(mode_str, &endptr, 8);
if (*endptr != '\0') {
fprintf(stderr, "错误: 无效的权限模式 '%s'。请使用八进制数(如 0644)。\n", mode_str);
exit(EXIT_FAILURE);
}

printf("=== 批量权限更改工具 ===\n");
printf("目录: %s\n", dir_path);
printf("文件模式: %s\n", pattern);
printf("文件名匹配: %s\n", file_pattern);
print_mode_summary(mode);
printf("递归: %s\n", recursive ? "是" : "否");
printf("详细输出: %s\n", verbose ? "是" : "否");

// 执行权限更改
int result;
if (recursive) {
result = change_permissions_recursive(dir_path, file_pattern, mode, verbose);
} else {
// 非递归处理
DIR *dir = opendir(dir_path);
if (!dir) {
perror("opendir");
exit(EXIT_FAILURE);
}

struct dirent *entry;
char full_path&#91;1024];
int changed_count = 0;
int error_count = 0;

while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}

// 检查文件名是否匹配模式
if (fnmatch(pattern, entry->d_name, 0) == 0) {
// 检查文件名是否匹配文件模式
if (fnmatch(file_pattern, entry->d_name, 0) == 0) {
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name);
if (chmod(full_path, mode) == -1) {
fprintf(stderr, "警告: 无法更改 '%s' 的权限: %s\n", full_path, strerror(errno));
error_count++;
} else {
if (verbose) {
printf("已更改 '%s' 的权限\n", full_path);
}
changed_count++;
}
}
}
}
closedir(dir);

if (error_count > 0) {
result = -1;
} else {
result = changed_count;
}
}

if (result == -1) {
fprintf(stderr, "\n权限更改过程中遇到错误。\n");
exit(EXIT_FAILURE);
} else {
printf("\n权限更改完成。成功更改了 %d 个文件的权限。\n", result);
}

return 0;
}

代码解释:

change_permissions_recursive 函数实现了递归的权限更改功能,使用 opendir 和 readdir 遍历目录。

它使用 fnmatch 函数来支持通配符模式匹配(如 *.txt, *.log)。

print_mode_summary 函数以人类可读的方式显示权限设置。

main 函数处理命令行参数,支持递归(-r)、详细输出(-v)和文件名模式匹配(-p)选项。

程序会统计成功更改的文件数量和错误数量。

示例 3:权限安全和最佳实践

这个例子重点演示权限设置的安全考虑和最佳实践。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>

// 创建具有特定权限的测试文件
void create_test_files() {
printf("=== 创建测试文件 ===\n");

// 1. 创建普通文件
FILE *fp = fopen("normal_file.txt", "w");
if (fp) {
fprintf(fp, "This is a normal file for permission testing.\n");
fclose(fp);
printf("创建普通文件: normal_file.txt\n");
}

// 2. 创建私密文件
fp = fopen("private_file.txt", "w");
if (fp) {
fprintf(fp, "This is a private file containing sensitive data.\n");
fclose(fp);
printf("创建私密文件: private_file.txt\n");
}

// 3. 创建脚本文件
fp = fopen("test_script.sh", "w");
if (fp) {
fprintf(fp, "#!/bin/bash\necho \"This is a test script.\"\n");
fclose(fp);
printf("创建脚本文件: test_script.sh\n");
}

// 4. 创建目录
if (mkdir("test_directory", 0755) == 0) {
printf("创建目录: test_directory\n");
}

printf("\n");
}

// 演示安全的权限设置
void demonstrate_secure_permissions() {
printf("=== 安全权限设置演示 ===\n");

// 1. 设置普通文件权限 (0644)
printf("1. 设置普通文件权限为 0644 (rw-r--r--)\n");
if (chmod("normal_file.txt", 0644) == 0) {
printf(" 成功: normal_file.txt 现在是 rw-r--r--\n");
} else {
printf(" 失败: %s\n", strerror(errno));
}

// 2. 设置私密文件权限 (0600)
printf("2. 设置私密文件权限为 0600 (rw-------)\n");
if (chmod("private_file.txt", 0600) == 0) {
printf(" 成功: private_file.txt 现在是 rw-------\n");
} else {
printf(" 失败: %s\n", strerror(errno));
}

// 3. 设置脚本文件权限 (0755)
printf("3. 设置脚本文件权限为 0755 (rwxr-xr-x)\n");
if (chmod("test_script.sh", 0755) == 0) {
printf(" 成功: test_script.sh 现在是 rwxr-xr-x\033&#91;0m\n");
} else {
printf(" 失败: %s\n", strerror(errno));
}

// 4. 设置目录权限 (0755)
printf("4. 设置目录权限为 0755 (rwxr-xr-x)\n");
if (chmod("test_directory", 0755) == 0) {
printf(" 成功: test_directory 现在是 rwxr-xr-x\033&#91;0m\n");
} else {
printf(" 失败: %s\n", strerror(errno));
}

printf("\n");
}

// 演示危险的权限设置
void demonstrate_dangerous_permissions() {
printf("=== 危险权限设置警告 ===\n");

printf("以下权限设置可能存在安全风险:\n");

// 1. 世界可写的文件
printf("1. 世界可写的普通文件 (0666)\n");
printf(" 风险: 任何用户都可以修改文件内容\n");
printf(" 建议: 使用 0644 代替\n");

// 2. 世界可执行的文件
printf("2. 世界可执行的敏感脚本 (0777)\n");
printf(" 风险: 任何用户都可以执行,可能存在安全漏洞\n");
printf(" 建议: 使用 0755 并确保脚本安全\n");

// 3. 私密文件设置不当
printf("3. 私密文件权限过于宽松 (0644)\n");
printf(" 风险: 组用户和其他用户可以读取私密信息\n");
printf(" 建议: 使用 0600 确保只有所有者可访问\n");

printf("\n");
}

// 演示权限检查
void demonstrate_permission_checking() {
printf("=== 权限检查最佳实践 ===\n");

struct stat sb;

// 检查私密文件权限
if (stat("private_file.txt", &sb) == 0) {
mode_t mode = sb.st_mode & 0777;
printf("检查 private_file.txt 当前权限: %04o\n", mode);

if (mode == 0600) {
printf("✓ 权限设置正确,只有所有者可读写\n");
} else if (mode & (S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) {
printf("✗ 警告: 权限过于宽松,组用户或其他用户有访问权限\n");
} else {
printf("- 权限设置合理\n");
}
}

// 检查脚本文件权限
if (stat("test_script.sh", &sb) == 0) {
mode_t mode = sb.st_mode & 0777;
printf("检查 test_script.sh 当前权限: %04o\n", mode);

if (mode & S_IXUSR) {
printf("✓ 所有者有执行权限\n");
} else {
printf("✗ 所有者没有执行权限,脚本可能无法运行\n");
}
}

printf("\n");
}

// 清理测试文件
void cleanup_test_files() {
printf("=== 清理测试文件 ===\n");
unlink("normal_file.txt");
unlink("private_file.txt");
unlink("test_script.sh");
rmdir("test_directory");
printf("清理完成\n");
}

int main() {
printf("当前用户: UID=%d, GID=%d\n", getuid(), getgid());
printf("\n");

// 创建测试文件
create_test_files();

// 演示安全权限设置
demonstrate_secure_permissions();

// 演示危险权限设置
demonstrate_dangerous_permissions();

// 演示权限检查
demonstrate_permission_checking();

// 清理
cleanup_test_files();

printf("\n=== 权限设置最佳实践总结 ===\n");
printf("普通文件: 0644 (rw-r--r--)\n");
printf("私密文件: 0600 (rw-------)\n");
printf("可执行文件: 0755 (rwxr-xr-x)\n");
printf("私密可执行文件: 0700 (rwx------)\n");
printf("目录: 0755 (rwxr-xr-x)\n");
printf("私密目录: 0700 (rwx------)\n");
printf("\n安全建议:\n");
printf("1. 遵循最小权限原则\n");
printf("2. 定期检查重要文件的权限\n");
printf("3. 避免使用 0777 或 0666 等过于宽松的权限\n");
printf("4. 对于敏感文件,使用 0600 或 0700\n");
printf("5. 理解权限位的含义,避免误操作\n");

return 0;
}

代码解释:

create_test_files 函数创建了几种不同类型的测试文件。

demonstrate_secure_permissions 演示了如何为不同类型的文件设置安全的权限。

demonstrate_dangerous_permissions 警告了一些常见的危险权限设置。

demonstrate_permission_checking 展示了如何检查现有文件的权限是否合理。

cleanup_test_files 负责清理创建的测试文件。

main 函数协调整个演示过程,并在最后总结权限设置的最佳实践。

编译和运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 编译示例
gcc -o chmod_example1 chmod_example1.c
gcc -o chmod_example2 chmod_example2.c -lpthread
gcc -o chmod_example3 chmod_example3.c

# 运行示例
# 示例1: 基本用法
touch testfile.txt
./chmod_example1 testfile.txt 0644
./chmod_example1 script.sh 0755

# 示例2: 批量处理
mkdir testdir
touch testdir/file1.txt testdir/file2.log
./chmod_example2 testdir "*.txt" 0644 -r -v

# 示例3: 安全演示
./chmod_example3

总结:

chmod 函数是 Linux 文件系统权限管理的核心工具。掌握其使用方法对于系统安全和文件访问控制至关重要。在使用时应遵循最小权限原则,根据文件的实际用途设置合适的权限,并定期检查重要文件的权限设置,以防止安全漏洞。

data-ad-format="auto" data-full-width-responsive="true">