CodeRoad Map 程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。
由 程序员柏风 独立维护 · 关于作者
学习 更多
文件操作与权限 cp/mv/rm、chmod、tar/gzip。
文件操作与权限
这一课你将能做到
用 cp / mv / rm / mkdir / tar 完成「部署一套应用」级别的文件搬运
看懂 rwxr-xr-x 并用八进制数字一次改对权限,解释 755 和 644 的含义
说清软链接和硬链接的区别,并用 ln -s 做「版本切换」这类生产常见操作
为什么要学
Java 工程师在生产环境最常做的文件操作:把新 jar 包传上去替换旧的、给部署脚本加执行权限、改 Nginx 配置后重启、把日志目录归档压缩。而权限是 Linux 的安全基石——部署脚本忘加 x 权限跑不起来,日志文件权限不对应用写不进去,chmod 777 滥用则是面试官最想听你批判的反面案例。
人话:文件操作是「搬东西」,权限是「门禁卡」。每个文件都有三张门禁卡(属主、属组、其他人),每张卡上写着能读(r)、能写(w)、能执行(x)。chmod 就是换卡,chown 就是换卡主。
先建立图像
权限的三层九位结构:
- rwx r-x r--
│ │ │ └── 其他人 others:只读
│ │ └────── 属组 group:读+执行
│ └────────── 属主 owner:读+写+执行
└───────────── 类型:- 文件,d 目录,l 软链接
二进制换算成八进制,这就是 chmod 数字:
权限 二进制 八进制 含义 rwx 111 7 读+写+执行 r-x 101 5 读+执行 rw- 110 6 读写 r-- 100 4 只读 --- 000 0 无权限
所以 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% 场景。
讲清楚要点
目录的 x 权限是「进入权」 :目录没有 x,你 cd 不进去;没有 r,你能进去但 ls 不出内容。所以目录普遍给 755。
cp 会覆盖同名文件且不提醒 :交互式 Shell 里 cp/rm 通常有 -i 别名保护,但脚本里没有。覆盖前先 cp 目标 目标.bak,或用 cp -n 禁止覆盖。
chmod 777 是运维红线 :它让所有人都能改能执行,等于门禁全拆。正确姿势是按需最小授权,属主该是谁就 chown 成谁。
软链接与硬链接的核心区别(面试必背) :软链接是「快捷方式」,存的是路径,原文件删除后它就悬空(红色失效);可跨文件系统、可指向目录。硬链接是同一个 inode 的另一个名字,删掉原文件数据仍在(链接数为 0 才真释放);不可跨文件系统、不可对目录。
ln -sfn 的 f 是「强制覆盖已有链接」 :不加 f,对已存在的软链接再执行 ln -s 会在链接指到的目录里新建一个子链接,这是新手最常见的翻车点。
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 755rm -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 紧跟包名,且在源路径之前
卡点急救
./run.sh 报 Permission denied :chmod +x run.sh。如果连目录都进不去,检查目录本身有没有 x 权限。
应用写日志报 Permission denied :三步定位——ls -ld 日志目录 看属主和权限 → ps -ef | grep java 确认应用运行用户 → sudo chown -R 运行用户 运行用户 目录。
误删文件怎么办 :生产环境第一时间停止往该磁盘写入(写入会覆盖被删数据),评估是否有备份/快照;普通开发机上 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 课展开。
自测三问
rwxr-x--- 对应的八进制是多少?
删除软链接的原文件后,访问软链接会发生什么?硬链接呢?
把 /opt/myapp/logs 整个目录归档为 tar.gz 并保留权限,用什么命令?
小结一句话 文件操作是搬东西、权限是门禁卡:755 给脚本和目录、644 给普通文件,软链接做版本切换,tar 一包一解完成部署搬运。
延伸