大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
文件操作与权限
这一课你将能做到
- 用 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 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 紧跟包名,且在源路径之前 |
卡点急救
./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 一包一解完成部署搬运。
延伸
- GNU Coreutils 官方手册
- 下一课:管道与文本处理——grep/awk/sed 组合技,一行命令翻完整个日志。