目录
[2.1 数字法:4读2写1执行](#2.1 数字法:4读2写1执行)
[2.2 符号法:精确微调](#2.2 符号法:精确微调)
[2.3 递归修改:-R参数](#2.3 递归修改:-R参数)
[3.1 chown:改变所有者和所属组](#3.1 chown:改变所有者和所属组)
[3.2 chgrp:专门改变所属组](#3.2 chgrp:专门改变所属组)
[3.3 一个完整的权限配置示例](#3.3 一个完整的权限配置示例)
[4.1 SUID:让程序以文件所有者的身份运行](#4.1 SUID:让程序以文件所有者的身份运行)
[4.2 SGID:继承目录的所属组](#4.2 SGID:继承目录的所属组)
[4.3 粘滞位:/tmp目录的保护神](#4.3 粘滞位:/tmp目录的保护神)
[4.4 特殊权限的数字表示](#4.4 特殊权限的数字表示)
一、引言:从"看懂权限"到"修改权限"
上一篇我们学会了用ls -l看懂权限:
text
-rw-r--r-- 1 zhangsan developers 1024 Apr 21 10:30 report.txt
现在的问题是:如果想让同组的同事也能编辑这个文件,该怎么改?
答案就是用chmod命令。它是"change mode"的缩写,专门用来修改文件和目录的权限。
二、chmod:修改权限的两种语法
chmod提供了两种语法来表达权限变更:数字法 和符号法。数字法适合整体设置,符号法适合局部微调。
2.1 数字法:4读2写1执行
数字法的核心是用一个三位数字来表示三组权限,每一位数字由4(读)、2(写)、1(执行)相加得到。
计算规则:
| 权限组合 | 计算过程 | 数字 |
|---|---|---|
| --- | 0+0+0 | 0 |
| --x | 0+0+1 | 1 |
| -w- | 0+2+0 | 2 |
| -wx | 0+2+1 | 3 |
| r-- | 4+0+0 | 4 |
| r-x | 4+0+1 | 5 |
| rw- | 4+2+0 | 6 |
| rwx | 4+2+1 | 7 |
三位数字分别对应:
-
第一位:所有者(user)权限
-
第二位:所属组(group)权限
-
第三位:其他人(others)权限
常用权限数字:
| 数字 | 权限字符串 | 典型用途 |
|---|---|---|
| 755 | rwxr-xr-x | 可执行程序、目录 |
| 644 | rw-r--r-- | 普通配置文件 |
| 600 | rw------- | 敏感配置文件(如SSH私钥) |
| 777 | rwxrwxrwx | 所有人可读可写可执行(危险!) |
使用示例:
bash
# 给脚本文件设置标准执行权限:所有者全权限,其他人只读和执行
chmod 755 script.sh
# 给配置文件设置标准权限:所有者可写,其他人只读
chmod 644 config.conf
# 给SSH私钥设置严格权限:只有所有者可读写
chmod 600 ~/.ssh/id_rsa
为什么SSH私钥必须是600?
如果你试图用权限过于宽松的私钥连接服务器,SSH会直接拒绝:
text
Permissions 0644 for 'id_rsa' are too open.
这是因为私钥被别人读取就等于密码泄露。600权限确保了只有你自己能读取这个文件。
2.2 符号法:精确微调
数字法适合"整体设置",但有时候你只想"给其他人加上写权限"或者"去掉执行权限",这时候符号法更直观。
符号法格式:
text
chmod [身份][操作符][权限] 文件
身份符号:
| 符号 | 含义 |
|---|---|
| u | 所有者(user) |
| g | 所属组(group) |
| o | 其他人(others) |
| a | 所有人(all,等同于ugo) |
操作符:
| 符号 | 含义 |
|---|---|
| + | 添加权限 |
| - | 移除权限 |
| = | 设置为指定权限 |
使用示例:
bash
# 给同组用户添加写权限
chmod g+w report.txt
# 移除其他人的读权限
chmod o-r secret.txt
# 给所有人添加执行权限
chmod a+x script.sh
# 同时操作多个身份
chmod u+x,g+x,o+x script.sh # 等同于 chmod a+x script.sh
# 精确设置:所有者可读写,组和其他人只读
chmod u=rw,go=r config.conf
数字法与符号法的选择策略:
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 初次设置权限 | 数字法 | 一次到位,清晰明确 |
| 小幅调整权限 | 符号法 | 不用重新计算整体数字 |
| 脚本中使用 | 数字法 | 更简洁,不容易出错 |
| 教学和理解 | 两者都学 | 实际工作中都会遇到 |
2.3 递归修改:-R参数
当需要修改整个目录及其所有子内容的权限时,使用-R(递归)参数:
bash
# 将整个网站目录设置为755
chmod -R 755 /var/www/html/
# 注意:文件一般不需要执行权限,目录需要执行权限
# 更好的做法是区分文件和目录
find /var/www/html -type f -exec chmod 644 {} \;
find /var/www/html -type d -exec chmod 755 {} \;
三、chown与chgrp:改变文件的主人
权限设置正确了,但文件属于谁也同样重要。
3.1 chown:改变所有者和所属组
chown(change owner)用于改变文件的所有者,也可以同时改变所属组。
bash
# 只改变所有者
sudo chown zhangsan file.txt
# 同时改变所有者和所属组(用冒号分隔)
sudo chown zhangsan:developers file.txt
# 只改变所属组(冒号前留空或使用.号)
sudo chown :developers file.txt
sudo chown .developers file.txt
递归修改所有权:
bash
sudo chown -R www-data:www-data /var/www/html/
这是部署Web应用时的常见操作:将网站文件的所有权交给Web服务器进程的用户(如www-data或nginx)。
3.2 chgrp:专门改变所属组
chgrp(change group)是chown的简化版,专门用来改变所属组:
bash
sudo chgrp developers file.txt
实际上用chown :组名可以达到同样效果,但chgrp在语义上更清晰。
3.3 一个完整的权限配置示例
假设你要部署一个Web应用,合理设置权限的流程:
bash
# 1. 将文件所有权交给Web服务器用户
sudo chown -R www-data:www-data /var/www/myapp/
# 2. 设置目录权限为755(所有者全权限,其他人只读和执行)
find /var/www/myapp -type d -exec chmod 755 {} \;
# 3. 设置文件权限为644(所有者可写,其他人只读)
find /var/www/myapp -type f -exec chmod 644 {} \;
# 4. 对于需要写入的目录(如上传目录),单独设置更宽松的权限
chmod 775 /var/www/myapp/uploads/
# 或者保持所有者不变,让Web服务器有写入权即可
四、特殊权限:SUID、SGID与粘滞位
除了基本的rwx九位权限外,Linux还有三个特殊权限位。它们不常用,但理解它们能解释很多系统行为。
4.1 SUID:让程序以文件所有者的身份运行
SUID(Set User ID) 作用于可执行文件 。当设置了SUID的程序被执行时,进程的有效用户ID会变成文件所有者的ID,而不是执行者的ID。
最经典的例子:passwd命令
bash
ls -l /usr/bin/passwd
# 输出:-rwsr-xr-x 1 root root 59976 Apr 21 10:30 /usr/bin/passwd
# ↑ 注意这个s,它出现在所有者执行权限的位置,表示SUID
/etc/shadow文件存储着所有用户的密码哈希,它的权限是:
bash
ls -l /etc/shadow
# 输出:-rw-r----- 1 root shadow 1024 Apr 21 10:30 /etc/shadow
普通用户没有权限直接修改/etc/shadow。但为什么普通用户可以修改自己的密码呢?
答案就在passwd命令的SUID位上:
-
普通用户执行
passwd命令 -
因为SUID位的存在,
passwd进程以root身份运行 -
root身份自然有权修改
/etc/shadow -
命令执行完毕,特权随之消失
设置SUID:
bash
chmod u+s /path/to/program # 符号法
chmod 4755 /path/to/program # 数字法(在普通权限前加4)
安全警告:SUID是一个强大的功能,但也可能成为安全隐患。如果SUID程序存在漏洞,攻击者可能通过它获取root权限。系统管理员需要定期审计系统中的SUID文件:
bash
find / -type f -perm -4000 -ls 2>/dev/null
4.2 SGID:继承目录的所属组
SGID(Set Group ID) 有两种作用,分别针对文件和目录。
作用于可执行文件时:类似SUID,程序执行时的有效组ID变成文件所属组。
作用于目录时:这才是SGID最常见的用途。当目录设置了SGID后:
-
在该目录下创建的新文件,其所属组会自动继承该目录的所属组
-
而不是使用创建者的默认组
实战场景:团队共享目录
假设有一个开发团队,所有成员都属于developers组。希望/shared/project目录下的所有文件,无论谁创建的,都属于developers组:
bash
# 创建共享目录
sudo mkdir -p /shared/project
# 设置所属组
sudo chgrp developers /shared/project
# 设置SGID
sudo chmod g+s /shared/project
# 或者用数字法:sudo chmod 2775 /shared/project
# 验证:目录权限显示为 drwxrwsr-x(注意中间的s)
ls -ld /shared/project
设置后,任何人在该目录下创建文件,文件都会自动属于developers组。
设置SGID:
bash
chmod g+s /path/to/dir # 符号法
chmod 2755 /path/to/dir # 数字法(在普通权限前加2)
4.3 粘滞位:/tmp目录的保护神
粘滞位(Sticky Bit) 只作用于目录 。它的功能是:即使目录所有人可写,用户也只能删除自己拥有的文件。
最经典的例子:/tmp目录
bash
ls -ld /tmp
# 输出:drwxrwxrwt 20 root root 4096 Apr 21 10:30 /tmp
# ↑ 注意这个t,它出现在其他人执行权限的位置
/tmp是系统的临时目录,任何用户都可以在里面创建文件。如果没有粘滞位保护,恶意用户可以删除别人的临时文件,造成服务异常。
有了粘滞位后:
-
用户A可以在
/tmp中创建文件 -
用户B可以读取这个文件(如果权限允许)
-
但用户B不能删除用户A的文件
验证实验:
bash
# 创建一个测试目录
mkdir test_sticky
# 设置为777权限(所有人可写)
chmod 777 test_sticky
# 此时任何人都可以在里面创建和删除任何文件
# 加上粘滞位
chmod +t test_sticky
# 或者 chmod 1777 test_sticky
# 查看权限变化
ls -ld test_sticky
# 输出:drwxrwxrwt ... test_sticky
设置粘滞位:
bash
chmod +t /path/to/dir # 符号法
chmod 1777 /path/to/dir # 数字法(在普通权限前加1)
4.4 特殊权限的数字表示
当使用数字法设置权限时,特殊权限作为第四位数字放在最前面:
| 数字 | 含义 | 示例 | 最终权限 |
|---|---|---|---|
| 4 | SUID | chmod 4755 file | -rwsr-xr-x |
| 2 | SGID | chmod 2755 dir | drwxr-sr-x |
| 1 | 粘滞位 | chmod 1777 dir | drwxrwxrwt |
组合使用:
bash
chmod 6755 file # 同时设置SUID和SGID(4+2=6)
chmod 3777 dir # 同时设置SGID和粘滞位(2+1=3)
五、完整速查表
基本权限数字对照
| 数字 | 权限 | 数字 | 权限 |
|---|---|---|---|
| 0 | --- | 4 | r-- |
| 1 | --x | 5 | r-x |
| 2 | -w- | 6 | rw- |
| 3 | -wx | 7 | rwx |
常用权限组合
| 数字 | 符号 | 适用场景 |
|---|---|---|
| 755 | rwxr-xr-x | 目录、可执行程序 |
| 644 | rw-r--r-- | 普通文件、配置文件 |
| 600 | rw------- | SSH私钥等敏感文件 |
| 775 | rwxrwxr-x | 共享目录(同组可写) |
| 777 | rwxrwxrwx | 所有人可写(危险) |
特殊权限速查
| 名称 | 作用对象 | 效果 | 设置命令 |
|---|---|---|---|
| SUID | 可执行文件 | 以文件所有者身份运行 | chmod u+s file |
| SGID | 目录 | 新建文件继承目录的所属组 | chmod g+s dir |
| 粘滞位 | 目录 | 用户只能删除自己的文件 | chmod +t dir |
命令速查
| 命令 | 功能 | 示例 |
|---|---|---|
| chmod 755 | 数字法设置权限 | chmod 755 script.sh |
| chmod g+w | 符号法添加权限 | chmod g+w file.txt |
| chown | 改变所有者 | chown user:group file |
| chgrp | 改变所属组 | chgrp group file |
| chmod -R | 递归修改 | chmod -R 755 dir/ |
六、动手练习
bash
# 1. 权限设置练习
touch test.txt
chmod 644 test.txt
ls -l test.txt # 应该显示 -rw-r--r--
chmod g+w test.txt
ls -l test.txt # 应该显示 -rw-rw-r--
chmod 755 test.txt
ls -l test.txt # 应该显示 -rwxr-xr-x
# 2. 所有权修改练习(需要sudo)
sudo chown root test.txt
ls -l test.txt # 所有者变为root
sudo chown $USER:$USER test.txt # 改回自己
ls -l test.txt
# 3. 粘滞位实验
mkdir sticky_test
chmod 777 sticky_test
# 切换另一个用户(或用su testuser创建测试用户)
# 在sticky_test中互相创建和删除文件,观察结果
chmod +t sticky_test
# 再次尝试互相删除文件,观察差异
# 4. 查找系统中的SUID文件
find /usr/bin -type f -perm -4000 -ls 2>/dev/null | head -10
# 5. 清理
rm test.txt
rmdir sticky_test
七、本篇小结
权限管理的两篇文章到这里就完整了。回顾一下:
上一篇我们理解了:
-
root与普通用户的区别
-
useradd、passwd、su、sudo的用法
-
rwx对文件和目录的不同含义
本篇我们掌握了:
-
chmod的数字法(4读2写1执行)和符号法
-
chown和chgrp改变所有权
-
SUID(提权执行)、SGID(继承组)、粘滞位(保护共享目录)三个特殊权限
核心认知:
-
755和644是记忆基数------90%的文件和目录用这两个数字就够了
-
特殊权限是"补丁"而非"日常"------理解它们的作用,但不滥用
-
权限的最小化原则------能用600就不用644,能用644就不用777
综合实战:为新项目设置完整权限
假设你要在/opt/myapp部署一个新应用:
-
应用由用户
appuser运行 -
开发团队属于
devteam组,需要能修改配置文件 -
上传目录
uploads需要应用能写入
bash
# 1. 创建目录结构
sudo mkdir -p /opt/myapp/{bin,conf,uploads}
# 2. 设置所有权
sudo chown -R appuser:devteam /opt/myapp
# 3. 设置基本权限
sudo chmod 755 /opt/myapp/{bin,conf}
sudo chmod 775 /opt/myapp/uploads # 应用需要写入
# 4. 设置SGID,确保新建文件属于devteam组
sudo chmod g+s /opt/myapp/conf
sudo chmod g+s /opt/myapp/uploads
# 5. 验证
ls -la /opt/myapp/
八、下篇预告
掌握了文件操作和权限管理,你已经具备了Linux系统管理的基础能力。但还有一个重要问题:软件怎么安装?
Windows下你习惯双击exe安装包,macOS下拖拽到Applications。Linux下则有一套完全不同的软件包管理哲学。
下一篇我们将进入软件包管理 的世界,学习apt(Debian系)和dnf/yum(RedHat系)的用法,以及源码编译安装的三部曲。你将理解为什么Linux用户说"装软件"时,很少去网站下载安装包。
延伸思考 :/tmp目录的粘滞位保护了用户文件不被他人删除,但它不能阻止他人读取你的文件 。如果你在/tmp下创建了一个敏感文件(如密码明文),其他用户虽然删不掉,但可以读取。如何保护/tmp下文件的私密性?提示:权限设为600,或者使用mktemp命令创建只有自己能访问的临时目录。