chmod (Change Mode) 是 Linux 權限管理的核心命令。掌握符號模式(直觀語義)與八進制模式(高效精確)雙軌操作,並理解 setuid/setgid/sticky 三大特殊權限位,是系統管理員的必修課。本文提供完整語法參考、實戰場景對比、遞歸陷阱避坑與自動化腳本模板。
| 主體 | 符號 | 八進制位 | 權限含義 |
|---|---|---|---|
| 用戶/擁有者 | u | 第 1 位 (64) | r=4, w=2, x=1 |
| 組 | g | 第 2 位 (8) | r=4, w=2, x=1 |
| 其他 | o | 第 3 位 (1) | r=4, w=2, x=1 |
| 所有 | a | — | u+g+o 合集 |
| 名稱 | 八進制 | 符號 | 文件效果 | 目錄效果 |
|---|---|---|---|---|
| SetUID | 4000 | u+s | 執行時獲得文件擁有者權限 | — |
| SetGID | 2000 | g+s | 執行時獲得文件組權限 | 新建文件繼承目錄組 |
| Sticky | 1000 | o+t | — | 僅擁有者/root可刪除文件(/tmp) |
chmod [ugoa...][+-=][rwxXst...] file...| 操作符 | 含義 |
|---|---|
+ | 添加權限 |
- | 移除權限 |
= | 精確設置(清除原有) |
# 1. 所有用戶加讀寫執行
chmod a+rwx file
chmod ugo+rwx file # 等效
# 2. 去除其他用戶寫權限
chmod o-w file
# 3. 設置用戶/組讀寫執行,其他唯讀
chmod u=rwx,g=rwx,o=r file
# 4. 遞歸:目錄加 x,文件不加 x (大 X 技巧)
chmod -R u+rwX,go+rX,go-w /path/to/dir
# X: 僅當是目錄或已有 x 時添加 x
# 5. 特殊位設置
chmod u+s /usr/bin/myapp # SetUID
chmod g+s /shared/team # SetGID (團隊協作目錄)
chmod o+t /tmp # Sticky bit
rwx = 4+2+1 = 7
rw- = 4+2+0 = 6
r-x = 4+0+1 = 5
r-- = 4+0+0 = 4
| 場景 | 八進制 | 符號等效 | ls -l 顯示 |
|---|---|---|---|
| 私有文件 | 600 | u=rw,go= | -rw------- |
| 腳本/執行文件 | 700 | u=rwx,go= | -rwx------ |
| 共享文件(組可寫) | 660 | u=rw,g=rw,o= | -rw-rw---- |
| Web 目錄 | 755 | u=rwx,g=rx,o=rx | drwxr-xr-x |
| 團隊協作目錄 | 2775 | u=rwx,g=rwx,o=rx + g+s | drwxrwsr-x |
| 公共臨時目錄 | 1777 | a=rwx + o+t | drwxrwxrwt |
| SetUID 程序 | 4755 | u=rxs,g=rx,o=rx | -rwsr-xr-x |
# 等效於 chmod a+rwx
chmod 777 file
# 僅擁有者全權,組讀執行,其他讀執行
chmod 755 script.sh
# 含特殊位:SetGID 目錄
chmod 2775 /shared/team
chmod -R 777 /var/www # 災難:所有文件變可執行,安全風險極大
chmod -R 644 /var/www # 災難:目錄失去 x,無法遍歷,網站掛掉
# 方法 1:find + xargs (標準、可控)
find /var/www -type d -exec chmod 755 {} +
find /var/www -type f -exec chmod 644 {} +
# 方法 2:chmod 大 X 技巧 (僅 GNU coreutils)
chmod -R u+rwX,go+rX,go-w /var/www
# 大 X: 如果是目錄或已有任意 x 權限,則添加 x
# 方法 3:配合 setgid 保持組所有權
find /shared/team -type d -exec chmod 2775 {} +
find /shared/team -type f -exec chmod 664 {} +
--reference 與批量同步# 以 reference_file 的權限為準
chmod --reference=reference_file target_file
# 批量同步某目錄權限到另一目錄 (結構相同)
cd /src && find . -type f -printf "chmod %m %p\n" | sed 's|^\./|/dst/|' | sh
stat -c "%a %n" file # 八進制權限 + 文件名
stat -c "%A %a %n" file # 符號權限 + 八進制 + 文件名
ls -l file # 傳統輸出
#!/bin/bash
# fix-perms.sh: 標準化 Web 目錄權限
# 用法: fix-perms.sh /var/www/html
TARGET="${1:-.}"
OWNER="${2:-www-data:www-data}"
echo "Fixing ownership..."
chown -R "$OWNER" "$TARGET"
echo "Fixing directory permissions (2775)..."
find "$TARGET" -type d -exec chmod 2775 {} +
echo "Fixing file permissions (664)..."
find "$TARGET" -type f -exec chmod 664 {} +
echo "Fixing script/executable permissions (755)..."
find "$TARGET" -type f -name "*.sh" -exec chmod 755 {} +
find "$TARGET" -type f -name "*.py" -exec chmod 755 {} +
echo "Done."
核心心法: 符號模式適合「微調」(加/減某權限),八進制適合「定型」(標準化部署)。遞歸操作必須區分文件與目錄,善用
find -type d/f或chmod 大 X。特殊位是雙刃劍:SetGID 利於協作,SetUID 極度危險(提權漏洞源頭),非必要不開啟。