CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Shell 与 Bash 入门/课时/文件操作与权限
RawBlame
课时目录12 节

Shell 与 Bash 入门

  1. 01Shell 是什么
  2. 02目录与文件导航
  3. 03文件操作与权限
  4. 04管道与文本处理
  5. 05变量与字符串
  6. 06条件与循环
  7. 07函数与脚本结构
  8. 08正则表达式
  9. 09进程与定时任务
  10. 10网络命令
  11. 11系统管理与编辑器
  12. 12综合练习

文件操作与权限

cp/mv/rm、chmod、tar/gzip。

35 分钟

文件操作与权限

这一课你将能做到

  1. 用 cp / mv / rm / mkdir / tar 完成「部署一套应用」级别的文件搬运
  2. 看懂 rwxr-xr-x 并用八进制数字一次改对权限,解释 755 和 644 的含义
  3. 说清软链接和硬链接的区别,并用 ln -s 做「版本切换」这类生产常见操作

为什么要学

Java 工程师在生产环境最常做的文件操作:把新 jar 包传上去替换旧的、给部署脚本加执行权限、改 Nginx 配置后重启、把日志目录归档压缩。而权限是 Linux 的安全基石——部署脚本忘加 x 权限跑不起来,日志文件权限不对应用写不进去,chmod 777 滥用则是面试官最想听你批判的反面案例。

人话:文件操作是「搬东西」,权限是「门禁卡」。每个文件都有三张门禁卡(属主、属组、其他人),每张卡上写着能读(r)、能写(w)、能执行(x)。chmod 就是换卡,chown 就是换卡主。

先建立图像

权限的三层九位结构:

- rwx r-x r--
│  │   │   └── 其他人 others:只读
│  │   └────── 属组 group:读+执行
│  └────────── 属主 owner:读+写+执行
└───────────── 类型:- 文件,d 目录,l 软链接

二进制换算成八进制,这就是 chmod 数字:

权限二进制八进制含义
rwx1117读+写+执行
r-x1015读+执行
rw-1106读写
r--1004只读
---0000无权限

所以 rwxr-xr-x = 755,rw-r--r-- = 644。背下来:脚本/目录 755,配置/普通文件 644。

跟着做

步骤 1:搭建文件操作沙盒

mkdir -p ~/file-lab && cd ~/file-lab
echo "v1" > app.jar
echo "server {" > nginx.conf
touch run.sh
ls -l

touch 的本义是更新文件时间戳,文件不存在时顺手创建,所以成了「快速建空文件」的惯用法。

步骤 2:复制、移动、重命名、删除

cp app.jar app.jar.bak          # 复制;cp -r 目录 目录2 复制目录
cp -a app.jar bak/app.jar 2>/dev/null || mkdir bak && cp -a app.jar bak/
mv app.jar myapp.jar            # 同盘移动=重命名;跨盘移动=搬移
mkdir rel-1.0 && mv rel-1.0 release-1.0   # mv 也能给目录改名
rm nginx.conf                   # 删单个文件,不可进回收站!
rm -r release-1.0               # 删目录必须 -r(递归)

生产铁律:rm -rf 之前,先用同样的路径模式跑一遍 ls,看清要删的到底是什么。rm 没有「撤销」。

步骤 3:读懂并修改权限

ls -l run.sh          # -rw-r--r--,没有执行位
chmod +x run.sh       # 三方都加执行权限
ls -l run.sh          # -rwxr-xr-x,即 755

chmod 644 nginx.conf  # 数字法一次设到位
chmod 750 run.sh      # 属主全权,属组读写执行,其他人无权

两种写法:+x/-x 是在现有权限上加减,数字法(755)是整体覆盖。写脚本、定规范用数字法,语义明确。

步骤 4:属主与属组

ls -l run.sh          # 属主 属组 都是你
sudo chown root:root run.sh      # 换成 root,需要 sudo
sudo chown deploy:deploy run.sh  # 改回来

典型场景:应用以 deploy 用户跑,日志目录却属于 root,应用写日志报 Permission denied——sudo chown -R deploy:deploy /opt/myapp/logs 一把改对(-R 递归)。

步骤 5:软链接做版本切换

mkdir -p ~/file-lab/versions/1.0 ~/file-lab/versions/2.0
echo "v1" > versions/1.0/app.jar
echo "v2" > versions/2.0/app.jar

ln -s ~/file-lab/versions/1.0 ~/file-lab/current    # 建软链接
cat ~/file-lab/current/app.jar                      # v1
ln -sfn ~/file-lab/versions/2.0 ~/file-lab/current  # 无缝切到 2.0
cat ~/file-lab/current/app.jar                      # v2
ls -l ~/file-lab/current                            # -> 指向 versions/2.0

这是 Nginx 配置管理、应用发布系统的标准手法:改一个链接,瞬间完成回滚。

步骤 6:打包压缩(部署必备)

tar -czf app-20260101.tar.gz opt/myapp/     # c 创建 z gzip 压缩 f 文件名
tar -tzf app-20260101.tar.gz | head         # t 只看包内容,不解压
mkdir restore && tar -xzf app-20260101.tar.gz -C restore   # x 解压,-C 指定去处

口诀:czf 打包,xzf 解包。别再背「这个参数是什么缩写」,背这两个组合就覆盖 90% 场景。

讲清楚要点

  1. 目录的 x 权限是「进入权」:目录没有 x,你 cd 不进去;没有 r,你能进去但 ls 不出内容。所以目录普遍给 755。
  2. cp 会覆盖同名文件且不提醒:交互式 Shell 里 cp/rm 通常有 -i 别名保护,但脚本里没有。覆盖前先 cp 目标 目标.bak,或用 cp -n 禁止覆盖。
  3. chmod 777 是运维红线:它让所有人都能改能执行,等于门禁全拆。正确姿势是按需最小授权,属主该是谁就 chown 成谁。
  4. 软链接与硬链接的核心区别(面试必背):软链接是「快捷方式」,存的是路径,原文件删除后它就悬空(红色失效);可跨文件系统、可指向目录。硬链接是同一个 inode 的另一个名字,删掉原文件数据仍在(链接数为 0 才真释放);不可跨文件系统、不可对目录。
  5. ln -sfn 的 f 是「强制覆盖已有链接」:不加 f,对已存在的软链接再执行 ln -s 会在链接指到的目录里新建一个子链接,这是新手最常见的翻车点。
  6. tar 的 f 必须紧跟文件名:tar -zcf 后面第一个参数必须是包名,-f 是「该参数吃文件名」的选项,参数顺序写错会报神秘错误。

你可能会懵的地方

  • chmod 755 里每个数字对应谁? 三个数字从左到右依次是:属主、属组、其他人。7=属主 rwx,5=属组 r-x,5=其他人 r-x。面试让你手推 rw-r-----,答 640。

  • 为什么新建文件默认是 664/644,新建目录默认是 775/755? 由 umask 决定。默认 umask 002/022:目录起始 777 减去 umask 得 775/755,文件起始 666 减去 umask 得 664/644(文件天生去掉 x 位,因为普通文件默认不该可执行)。umask 命令可查看。

  • 删除一个文件后空间没释放,为什么? 大概率有进程还握着这个文件的句柄(典型:rm 了正在写的日志)。用 lsof | grep deleted 找到进程,重启或 truncate 该文件才真正释放空间。这是高频生产事故题。

  • cp -a 和 cp -r 有什么区别? -r 只递归复制内容;-a = 递归 + 保留权限、属主、时间戳,做备份和迁移用 -a,否则新文件的属主会变成执行 cp 的用户。

  • 软链接指向相对路径还是绝对路径好? 看场景。目录结构整体搬移的用相对路径(链接跟着目录走);指向固定版本库的用绝对路径更直观。ls -l 能看到链接真实指向,readlink -f 链接 输出解析后的绝对路径。

错法对照

错法问题正解
chmod -R 777 /opt/myapp全员可写可执行,安全隐患chown -R 给对属主 + chmod -R 755
rm -rf $DIR/(DIR 为空变量时)变成 rm -rf /,删根目录删前 [ -n "$DIR" ] 校验,路径加引号
cp -r src dst 后属主变了只复制了内容没保留元数据用 cp -a
对已有软链接直接 ln -s 新目标链接套链接,结构错乱ln -sfn 新目标 链接名
tar -czf xxx.tar.gz 文件1 文件2 顺序随意报错或打进奇怪的路径f 紧跟包名,且在源路径之前

卡点急救

  1. ./run.sh 报 Permission denied:chmod +x run.sh。如果连目录都进不去,检查目录本身有没有 x 权限。
  2. 应用写日志报 Permission denied:三步定位——ls -ld 日志目录 看属主和权限 → ps -ef | grep java 确认应用运行用户 → sudo chown -R 运行用户 运行用户 目录。
  3. 误删文件怎么办:生产环境第一时间停止往该磁盘写入(写入会覆盖被删数据),评估是否有备份/快照;普通开发机上 testdisk、extundelete 有几率找回,但别抱太大希望,预防靠备份和 rm 前确认。

面试常问

  • chmod 755 和 644 分别适用于什么?数字怎么算? 755 = 属主 rwx、属组和其他人 r-x,适用于脚本、可执行文件和目录;644 = 属主 rw、属组和其他人 r,适用于普通文件如配置、日志。数字是把每组 rwx 当三位二进制读出来的八进制值:r=4、w=2、x=1,7=4+2+1,5=4+1。

  • 软链接和硬链接的区别? 软链接是独立文件,存目标路径,原文件删了就悬空,可跨分区、可指目录;硬链接是同一 inode 的多个目录项,删除任一名字数据不丢(直到链接数归零),不能跨文件系统、不能对目录创建。ls -li 的第一列 inode 号相同即为硬链接。

  • 磁盘显示已满但 du 统计出来的总量不大,怎么排查? 两类可能:一是已删除但被进程占用的文件(lsof | grep deleted),重启对应进程或 truncate -s 0 释放;二是 inode 耗尽(海量小文件),df -i 查看 inode 使用率。这个问题的答案本身就在第 11 课展开。

自测三问

  1. rwxr-x--- 对应的八进制是多少?
  2. 删除软链接的原文件后,访问软链接会发生什么?硬链接呢?
  3. 把 /opt/myapp/logs 整个目录归档为 tar.gz 并保留权限,用什么命令?

小结一句话

文件操作是搬东西、权限是门禁卡:755 给脚本和目录、644 给普通文件,软链接做版本切换,tar 一包一解完成部署搬运。

延伸

  • GNU Coreutils 官方手册
  • 下一课:管道与文本处理——grep/awk/sed 组合技,一行命令翻完整个日志。
加载本节练习…
← 上一课目录与文件导航下一课 →管道与文本处理