TL;DR
系列方向: 从 Linux 基础命令开始,逐步掌握文件管理、权限控制、进程管理、网络排查、日志分析和 Shell 自动化,通过真实工作场景提升 Linux 工程实践能力。
本篇重点: 理解 Linux 文件权限的组成,学会使用 chmod 修改文件权限,使用 chown 修改文件所有者,使用 chgrp 修改所属用户组,并结合自动化测试脚本、日志目录和服务部署场景,解决常见的权限不足问题。
一、为什么文件存在,却还是无法使用?
在 Linux 服务器上,经常会遇到这样的情况:
明明脚本文件已经上传了,却无法执行:
bash
./run_test.sh
系统提示:
text
bash: ./run_test.sh: Permission denied
还有一种情况:
测试程序已经启动,但写日志时提示:
text
Permission denied
甚至有时候,文件可以正常读取,却不能修改。
这些问题都可能和 Linux 文件权限有关。
Linux 并不是只判断文件是否存在,还要判断当前用户是否拥有对应的操作权限。
先来看一个常见的文件列表:
bash
ls -l
输出示例:
text
-rw-r--r-- 1 root root 1024 Nov 9 09:00 test.conf
-rwxr-xr-x 1 root root 256 Nov 9 09:01 run_test.sh
drwxr-xr-x 2 root root 4096 Nov 9 09:02 logs
其中最前面的内容:
text
-rw-r--r--
就是文件权限信息。
要真正掌握权限管理,首先需要看懂这串字符。
二、Linux 文件权限到底怎么看?
1. 权限字符的组成
Linux 常见的权限字符包括:
| 字符 | 含义 |
|---|---|
r |
Read,读取权限 |
w |
Write,写入权限 |
x |
Execute,执行权限 |
- |
没有对应权限 |
例如:
text
-rwxr-xr--
可以拆分成四部分:
text
- | rwx | r-x | r--
含义如下:
| 部分 | 对应对象 | 权限 |
|---|---|---|
第一个字符 - |
文件类型 | 普通文件 |
rwx |
文件所有者 | 读取、写入、执行 |
r-x |
所属用户组 | 读取、执行 |
r-- |
其他用户 | 只读 |
如果第一个字符是 d,表示这是一个目录。
例如:
text
drwxr-xr-x
说明这是一个目录,所有者具有读、写、执行权限,用户组和其他用户具有读、执行权限。
2. 文件和目录的权限有什么区别?
这里有一个非常容易混淆的地方。
对于普通文件:
r:可以读取文件内容。w:可以修改文件内容。x:可以执行文件。
对于目录:
r:可以读取目录中的文件名称列表。w:可以在目录中创建、删除或重命名目录项,通常还需要同时具有x。x:可以进入目录,也可以访问其中已知名称的文件(还需要满足对应文件权限)。
也就是说,目录的 x 并不是运行目录,而是表示能否进入和访问目录内容。
例如:
bash
mkdir test_dir
chmod 600 test_dir
此时目录虽然有读取和写入权限,但没有执行权限,普通用户通常无法正常进入目录或访问其中的文件。
因此,配置目录权限时,不能只关注 r 和 w,还需要考虑 x。
3. Linux 权限的数字表示
除了字符形式,Linux 还支持数字形式表示权限。
对应关系:
| 权限 | 数值 |
|---|---|
r |
4 |
w |
2 |
x |
1 |
- |
0 |
将权限值相加,就可以得到对应数字。
例如:
text
rwx = 4 + 2 + 1 = 7
rw- = 4 + 2 = 6
r-x = 4 + 1 = 5
r-- = 4
因此:
text
rwxr-xr--
对应数字就是:
text
754
三个数字分别代表:
- 第一个数字:文件所有者。
- 第二个数字:所属用户组。
- 第三个数字:其他用户。
常见权限对照:
| 数字权限 | 字符权限 | 含义 |
|---|---|---|
777 |
rwxrwxrwx |
所有人可读、写、执行 |
755 |
rwxr-xr-x |
所有者可读写执行,其他人可读执行 |
644 |
rw-r--r-- |
所有者可读写,其他人只读 |
600 |
rw------- |
只有所有者可读写 |
700 |
rwx------ |
只有所有者可读写执行 |
750 |
rwxr-x--- |
所有者可读写执行,组用户可读执行 |
这里建议记住 755、644、600、700 这几个常见权限。
三、chmod:修改文件权限
chmod 是 Linux 中最常用的权限修改命令。
基本语法:
bash
chmod [选项] 权限 文件名
例如:
bash
chmod 755 run_test.sh
表示将脚本文件权限修改为 755。
1. 使用数字方式修改权限
先创建一个练习文件:
bash
mkdir -p ~/linux-practice/day06
cd ~/linux-practice/day06
touch test.sh
ls -l test.sh
修改为 755:
bash
chmod 755 test.sh
再次查看:
bash
ls -l test.sh
权限会变成类似:
text
-rwxr-xr-x
再修改为 644:
bash
chmod 644 test.sh
此时文件变为:
text
-rw-r--r--
可以看到,数字权限可以非常直接地控制文件权限。
2. 使用字符方式修改权限
除了数字方式,还可以直接使用 u、g、o、a 表示权限对象。
| 字符 | 含义 |
|---|---|
u |
文件所有者 |
g |
所属用户组 |
o |
其他用户 |
a |
所有用户 |
权限操作符:
| 符号 | 含义 |
|---|---|
+ |
增加权限 |
- |
移除权限 |
= |
设置为指定权限 |
例如:
给文件所有者增加执行权限:
bash
chmod u+x test.sh
移除其他用户的写权限:
bash
chmod o-w test.sh
给所属用户组增加读取权限:
bash
chmod g+r test.sh
将所有用户的权限统一设置为只读:
bash
chmod a=r test.sh
这种写法的好处是:不需要重新计算整个权限数字,只修改自己关心的部分。
3. 给 Shell 脚本增加执行权限
这是测试工作中经常遇到的场景。
创建一个简单的脚本:
bash
cat > run_test.sh <<'EOF'
#!/bin/bash
echo "开始执行自动化测试"
echo "测试执行完成"
EOF
尝试执行:
bash
./run_test.sh
如果当前文件没有执行权限,可能会提示:
text
Permission denied
先查看权限:
bash
ls -l run_test.sh
假设显示:
text
-rw-r--r--
可以看到,文件所有者没有执行权限。
执行:
bash
chmod u+x run_test.sh
再查看:
bash
ls -l run_test.sh
现在应该可以看到所有者权限中出现了 x。
执行脚本:
bash
./run_test.sh
预期输出:
text
开始执行自动化测试
测试执行完成
这里还有一个容易忽略的细节:
bash
bash run_test.sh
这种方式是让 Bash 解释器读取并执行脚本,通常不要求脚本本身具有执行权限;而:
bash
./run_test.sh
是直接执行脚本文件,需要满足执行权限以及其他执行条件。
4. 递归修改目录权限
如果想修改某个目录下所有文件和子目录的权限,可以使用 -R:
bash
chmod -R 755 scripts/
-R 表示递归处理。
不过,这里要特别提醒:
不要随意对整个项目目录执行 chmod -R 777。
这样可能让配置文件、脚本甚至敏感文件都变成所有用户可写,带来安全风险。
而且目录和普通文件的权限需求并不相同。
例如:
- 普通脚本可能需要
755。 - 普通配置文件通常只需要
644。 - 存放敏感配置的文件可能需要
600。 - 目录通常需要执行权限,才能正常进入和访问。
因此,批量修改权限前,应该先确认目录中的文件类型和实际用途。
5. 实际场景:给自动化测试脚本授权
假设测试项目结构如下:
text
api-test/
├── scripts/
│ ├── run_test.sh
│ └── clean.sh
├── config/
│ └── test.conf
└── logs/
可以分别设置权限:
bash
chmod 755 api-test/scripts/run_test.sh
chmod 755 api-test/scripts/clean.sh
chmod 644 api-test/config/test.conf
这样脚本可以执行,配置文件则不需要开放执行权限。
这比直接对整个项目目录使用 chmod 777 合理得多。
四、chown:修改文件所有者
chmod 解决的是权限问题。
但有时候,文件权限看起来没有问题,当前用户依然无法正常操作。
这可能是因为文件所有者不正确。
例如:
bash
ls -l test.conf
输出:
text
-rw-r--r-- 1 root root 128 Nov 9 09:00 test.conf
这里:
text
root root
分别表示:
- 第一个
root:文件所有者。 - 第二个
root:所属用户组。
如果当前测试服务使用 tester 用户运行,而配置文件归属于 root,那么 tester 可能无法修改这个文件。
这时候就需要使用 chown。
1. 修改文件所有者
基本语法:
bash
chown 用户名 文件名
例如:
bash
sudo chown tester test.conf
表示将文件所有者修改为 tester。
查看结果:
bash
ls -l test.conf
如果操作成功,所有者就会发生变化。
注意:修改其他用户拥有的文件所有权通常需要管理员权限,因此这里使用了 sudo。
2. 同时修改所有者和用户组
可以使用:
bash
sudo chown tester:tester test.conf
其中:
tester:新的文件所有者。tester:新的所属用户组。
也可以只修改所属用户组:
bash
sudo chown :tester test.conf
不过,如果只想修改用户组,使用 chgrp 也可以完成。
3. 递归修改目录所有权
例如:
bash
sudo chown -R tester:tester api-test/
表示将 api-test 目录以及内部文件、子目录的所有者和所属用户组修改为 tester。
这种操作在部署测试项目时比较常见。
但要注意:递归修改可能影响目录下所有文件的原有归属。
如果项目中包含由其他服务用户管理的文件,不要直接执行递归修改。
4. 实际场景:测试项目归属错误
假设测试项目由管理员用户创建:
bash
sudo mkdir -p /opt/api-test
sudo touch /opt/api-test/test.log
查看文件:
bash
ls -l /opt/api-test
假设文件归属于:
text
root root
现在需要让 tester 用户负责这个项目。
可以执行:
bash
sudo chown -R tester:tester /opt/api-test
然后确认:
bash
ls -ld /opt/api-test
ls -l /opt/api-test
如果归属修改成功,tester 就成为该目录及其内部文件的新所有者。
当然,实际部署时还要结合服务运行用户、目录权限和安全要求进行设置。
五、chgrp:修改文件所属用户组
Linux 文件除了所有者,还有所属用户组。
如果多个用户需要共同访问一个项目目录,就可以通过用户组管理权限。
chgrp 用于修改文件或目录的所属用户组。
基本语法:
bash
chgrp 用户组 文件名
1. 修改文件所属用户组
例如:
bash
sudo chgrp testers test.log
表示将 test.log 的所属用户组修改为 testers。
查看:
bash
ls -l test.log
可以看到用户组发生了变化。
2. 递归修改目录所属用户组
bash
sudo chgrp -R testers logs/
表示修改 logs 目录及其内部文件的所属用户组。
3. chown 和 chgrp 有什么区别?
这两个命令很容易混淆。
| 命令 | 主要作用 | 示例 |
|---|---|---|
chown |
修改文件所有者,也可以修改所属用户组 | chown tester:tester test.log |
chgrp |
修改文件所属用户组 | chgrp testers test.log |
如果只需要修改用户组,使用 chgrp 更直接。
如果需要同时修改所有者和用户组,使用 chown 更方便。
4. 实际场景:多个测试人员共享日志目录
假设测试团队有一个用户组:
text
testers
多个测试人员都需要访问:
text
/opt/api-test/logs
可以将日志目录的所属用户组设置为 testers:
bash
sudo chgrp -R testers /opt/api-test/logs
然后再根据实际需求配置目录和文件权限。
例如:
bash
sudo chmod 775 /opt/api-test/logs
这样所有者和所属用户组都具有读、写、执行权限,其他用户只有读取和进入权限。
不过,仅修改用户组还不够:具体用户必须属于 testers 组,才能获得组权限。
六、综合实战:解决自动化测试项目权限问题
前面分别学习了三个命令,现在通过一个完整场景串起来。
假设我们有一个自动化测试项目:
text
/opt/api-test/
├── scripts/
│ └── run_test.sh
├── config/
│ └── test.conf
└── logs/
目前存在三个问题:
- 测试脚本无法执行。
- 测试用户无法写入日志。
- 项目目录归属不正确。
假设服务器已经创建了 tester 用户和 testers 用户组,并且当前账号具有相应的管理员权限。
第一步:查看当前权限
bash
ls -l /opt/api-test/scripts/
ls -l /opt/api-test/config/
ls -ld /opt/api-test/logs/
先确认文件和目录的所有者、用户组以及权限。
不要看到权限不足就直接执行 chmod 777。
第二步:修改项目所有者和用户组
bash
sudo chown -R tester:testers /opt/api-test
让项目归属于 tester 用户和 testers 用户组。
第三步:设置脚本执行权限
bash
sudo chmod 755 /opt/api-test/scripts/run_test.sh
第四步:设置配置文件权限
bash
sudo chmod 640 /opt/api-test/config/test.conf
这样文件所有者可以读写,所属用户组可以读取,其他用户没有权限。
第五步:设置日志目录权限
bash
sudo chmod 2775 /opt/api-test/logs
这里的 2 是目录的 Setgid 特殊权限位。
对于目录设置 Setgid 后,在该目录下新建的文件和子目录通常会继承目录所属的用户组。
这对多个测试人员共同维护日志目录很有帮助。
查看:
bash
ls -ld /opt/api-test/logs
可能看到类似:
text
drwxrwsr-x
其中组权限位置的 s 就表示 Setgid 已设置。
需要注意:Setgid 主要影响新建文件和目录的组归属,并不会自动保证所有新文件都具有组写权限。实际权限还会受到创建进程的 umask 等因素影响。
第六步:验证权限是否生效
切换到测试用户:
bash
sudo -u tester -H bash
尝试执行脚本:
bash
/opt/api-test/scripts/run_test.sh
再尝试创建日志:
bash
echo "test started" >> /opt/api-test/logs/test.log
如果两项操作都成功,说明基本权限配置符合当前测试场景。
退出测试用户:
bash
exit
这套操作覆盖了文件所有权、用户组和权限三个方面,也是 Linux 项目部署中比较常见的一类处理方式。
七、常见权限问题排查
实际遇到权限错误时,我建议按照下面的顺序检查。
1. 查看当前用户
bash
whoami
确认当前使用哪个账号执行命令。
2. 查看用户所属组
bash
id
可以看到当前用户的 UID、GID 和所属用户组。
3. 查看文件权限
bash
ls -l test.sh
确认文件所有者、所属用户组以及权限。
4. 查看目录权限
bash
ls -ld logs/
注意:文件本身有权限,并不意味着它所在的目录一定允许访问。
5. 检查完整路径权限
可以使用:
bash
namei -l /opt/api-test/logs/test.log
这个命令会逐级展示路径中各级目录和文件的权限。
例如:
text
f: /opt/api-test/logs/test.log
drwxr-xr-x root root /
drwxr-xr-x root root opt
drwxr-xr-x tester testers api-test
drwxrwxr-x tester testers logs
-rw-rw-r-- tester testers test.log
如果中间某一级目录缺少必要的访问权限,即使最终文件权限看起来正常,也可能无法访问。
6. 根据问题选择处理方式
| 问题 | 优先检查 | 可能的处理方式 |
|---|---|---|
| 脚本无法执行 | 是否有执行权限 | chmod u+x |
| 文件无法修改 | 所有者和写权限 | 检查 chown、chmod |
| 日志无法写入 | 日志目录权限 | 检查目录的 w、x |
| 用户无法访问目录 | 目录权限和用户组 | 检查 chmod、chgrp |
| 文件归属不正确 | 所有者和用户组 | chown |
| 多人无法共享文件 | 用户组及组权限 | chgrp、chmod |
这里需要强调:权限不足不一定都应该通过修改权限解决。有些目录本来就不应该开放给普通用户,应该先确认业务上是否需要访问,再决定如何调整。
八、动手练习
建议在自己的 Linux 环境中完成以下练习。
练习一:查看文件权限
bash
touch test.txt
ls -l test.txt
要求:观察文件默认权限,并解释每一部分代表什么。
练习二:修改文件权限
bash
chmod 600 test.txt
ls -l test.txt
要求:将文件设置为只有所有者可以读取和写入。
练习三:增加脚本执行权限
bash
touch run.sh
chmod u+x run.sh
ls -l run.sh
要求:给文件所有者增加执行权限。
练习四:修改文件所有者
在具有管理员权限的环境中,创建一个练习文件:
bash
sudo touch owner-test.txt
查看文件归属:
bash
ls -l owner-test.txt
尝试修改所有者:
bash
sudo chown "$USER" owner-test.txt
要求:确认文件所有者是否发生变化。
练习五:修改所属用户组
bash
sudo chgrp "$(id -gn)" owner-test.txt
要求:将文件所属用户组修改为当前用户的主组,并检查结果。
练习六:综合练习
创建一个简单的项目目录:
bash
mkdir -p permission-demo/{scripts,config,logs}
创建文件:
bash
touch permission-demo/scripts/run.sh
touch permission-demo/config/test.conf
设置权限:
bash
chmod 755 permission-demo/scripts/run.sh
chmod 640 permission-demo/config/test.conf
chmod 750 permission-demo/logs
最后检查:
bash
ls -lR permission-demo
要求:解释为什么脚本、配置文件和日志目录采用不同的权限。
九、总结
本篇学习了 Linux 文件权限管理中三个重要命令:
chmod:修改文件和目录权限。chown:修改文件所有者,也可以修改所属用户组。chgrp:修改文件所属用户组。
除此之外,还需要理解 Linux 权限的基本组成:
r:读取。w:写入。x:执行,对于目录则表示进入和访问能力。u、g、o:分别代表所有者、所属组和其他用户。
我认为,权限管理最重要的不是记住 755、644 这些数字,而是先弄清楚谁需要访问文件、需要执行什么操作,再给出恰当的权限。
尤其是在测试服务器和生产服务器上,不要为了图方便直接使用 chmod 777。权限开放得越大,并不代表问题解决得越好。