【Linux 命令实战(06):Linux 文件权限管理,掌握 chmod、chown、chgrp】

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/

目前存在三个问题:

  1. 测试脚本无法执行。
  2. 测试用户无法写入日志。
  3. 项目目录归属不正确。

假设服务器已经创建了 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。权限开放得越大,并不代表问题解决得越好。

相关推荐
艺杯羹1 小时前
1Panel 装好后 ufw 仍是 inactive:一次服务器安全盲区复盘
服务器·数据库·安全·网络安全·系统架构·实战·1panel
陈希1231 小时前
负载均衡与高可用:LVS、HAProxy、Keepalived 实战
运维·负载均衡·lvs
一条破秋裤2 小时前
【1114】【并发控制】【笔记】
linux
2035去旅行3 小时前
ADB的底层原理
linux·adb·嵌入式·arm·soc
武子康3 小时前
单卡 A6000 跑 Qwen-Drive:怎样留下可比较的第一条基线?
linux·人工智能·深度学习
女神下凡4 小时前
芯参谋(107):杰理AC_中科蓝讯_开发指南
linux·服务器·网络·单片机·嵌入式硬件
落羽的落羽4 小时前
【C++】C++17的主要特性
linux·服务器·开发语言·c++·算法·机器学习
SQL775 小时前
IT运维发展史,一部宏伟史诗
运维·运维发展史
分布式存储与RustFS6 小时前
Terraform 状态文件老在本地丢、并发还撞锁:把 state 锁进 RustFS
运维·云原生·开源·对象存储·分布式存储·s3·性能基准