文件与目录常用操作
校招考察频度:★ 高频(日常开发必备·手撕排查基石) 一句话速记:大文件查看必用
less绝不用vim/cat;追踪生产轮转日志必用tail -F而非tail -f;清理旧日志用find ... -mtime +30配合xargs;软链接是独立 inode 存路径,硬链接是共享同一 inode 引用。
在 Linux 操作系统中,“一切皆文件”。掌握高效的文件与目录操作,是日常开发部署、查找配置与生产日志排障的基本功。
一、目录浏览与路径导航
1. 核心命令与实用参数
| 命令与参数 | 作用说明 | 生产高频用法 |
|---|---|---|
pwd | 显示当前所在工作目录绝对路径 | 确认当前路径,防止误删错目录 |
cd ~ 或 cd | 快速回到当前用户的主目录(Home 目录) | 切换到个人根目录 |
cd - | 快速切回上一次的工作目录 | 在两个深层目录之间反复横跳极为高效 |
cd .. | 切换到上一级父目录 | 向上跳一级 |
ls -lh | 以人类可读形式(K/M/G)列出文件详细信息 | 快速查看文件大小与权限 |
ls -la | 显示所有文件,包含以 . 开头的隐藏文件 | 查看 .bashrc、.env、.git 等配置 |
ls -lt | 按文件修改时间从新到旧降序排列 | 快速找刚刚生成的日志或构建包 |
ls -lS | 按文件大小从大到小降序排列 | 快速识别当前目录下的最大文件 |
二、文件与目录的增删复制与移动
1. 增、删、改基本操作
# 1. 递归创建多级目录(若父目录不存在会自动创建)
mkdir -p /data/app/logs/2026/
# 2. 创建空文件或刷新已有文件的最后修改时间
touch app.env
# 3. 递归复制目录(-r 递归,-p 保留原文件的权限与时间戳属性)
cp -rp /data/app/conf /data/app/conf.bak
# 4. 移动文件或重命名
mv app-old.jar app.jar
mv /tmp/download.tar.gz /data/packages/
# 5. 递归强制删除目录及文件(极度危险,需谨慎使用)
rm -rf /data/app/temp_cache/2. 生产环境 rm -rf 事故预防规范
三、软链接 vs 硬链接(面试核心考点)
在 Linux 文件系统中,文件名只是目录项对底层 inode 的引用。每个文件由唯一的 inode 标识元数据,文件名则是指向 inode 的快捷指针。
硬链接(共享同一 inode)与软链接(独立 inode 存路径)对比
| 对比维度 | 软链接(Symbolic Link / 符号链接) | 硬链接(Hard Link) |
|---|---|---|
| 创建命令 | ln -s target link_name | ln target link_name |
| inode 关系 | 拥有全新的独立 inode,其内容仅仅是目标文件的路径字符串 | 共享同一个 inode 号,实质是同一个文件的不同名字 |
| 跨文件系统 | 支持(可以跨分区、跨硬盘挂载点) | 不支持(只能在同一个文件系统分区内部创建) |
| 能否链接目录 | 支持(非常常用,如版本软链) | 不支持(防止在文件目录树中产生无限循环拓扑) |
| 删除源文件的后果 | 软链接变成“死链/悬挂链接”,无法再打开访问 | 硬链接仍然完好,原 inode 引用计数减 1,只有当计数为 0 时才真正释放数据块 |
生产实战场景:无感版本热切换
# 线上部署目录通常保持恒定路径:/opt/app/current
# 升级版本只需修改软链接指向,无需修改上游 Nginx 或环境变量配置:
ln -sfn /opt/app/releases/v1.0.2 /opt/app/current四、文件内容查看与日志追踪选型
线上服务器排查 Bug 时,根据文件大小和场景选择正确的工具至关重要:
文件与日志查看工具选型决策树
| 工具 | 适用场景 | 核心优势 | 生产避坑 |
|---|---|---|---|
cat | 小型配置文件(几十行以内) | 一次性全部打印,支持 -n 标行号 | 严禁在 GB 级大日志文件使用,会导致终端卡死并消耗大量 IO |
head | 查看文件头部(如 head -n 20 app.log) | 快速确认日志文件的开头内容、格式头 | 配合管道提取前 N 行 |
tail | 查看文件尾部(如 tail -n 50 app.log) | 快速获取最新写入的异常记录 | -n 控制行数 |
less | GB 级大日志文件交互式检索 | 惰性分页加载,按需读内存,不占爆资源 | 掌握内部快捷键进行关键字检索 |
tail -f | 实时滚动追踪正在追加写入的日志 | 实时观察接口调用报错 | 日志轮转切割时会停止追踪 |
1. less 大文件高效浏览快捷键清单
当线上日志有数十 GB 时,使用 less app.log 打开是性能最优解:
- 搜索:输入
/pattern按回车向前搜索;按n跳转下一个匹配项,按N跳转上一个匹配项;输入?pattern向后搜索; - 移动:
G:直接跳转到文件最末尾(相当于 tail);g:跳转到文件最开头;- 空格键 /
f:向下滚动一屏; b:向上回滚一屏;
- 退出:输入
q(quit)立即退出。
2. tail -f vs tail -F(高频踩坑与面试题)
面试高频提问:“线上运行 Logrotate 日志按天切割后,tail -f 为什么抓不到新日志了?”
tail -f(小写 f,follow descriptor):- 根据文件描述符 / inode 进行追踪。
- 当日志工具执行轮转切割(例如将
app.log重命名为app.log.2026-10-08,并新建一个空app.log继续写)时,旧文件的 inode 变了或停止写入,tail -f仍然死守在旧的重命名文件上,导致控制台彻底“静止”!
tail -F(大写 F,follow name + retry):- 根据文件名进行追踪(相当于
--follow=name --retry)。 - 当发现
app.log文件被重命名或重建时,会自动关闭旧文件句柄,重新探测并打开新的app.log继续输出。排查轮转日志强烈推荐使用tail -F。
- 根据文件名进行追踪(相当于
五、文件高效查找:find
当需要全盘或在多层嵌套目录中检索符合条件的文件时,find 是最强大的工具。
1. 常用匹配维度
# 1. 按名称查找(支持通配符,建议加双引号避免 shell 提前展开)
find /var/log -name "*.log"
# 2. 忽略大小写查找
find /data -iname "*error*"
# 3. 按类型查找(-type f 为普通文件,-type d 为目录,-type l 为符号链接)
find /opt/app -type f -name "*.jar"
# 4. 按文件大小查找(+100M 大于 100MB,-10k 小于 10KB)
find /var/log -type f -size +100M
# 5. 按修改时间查找(+7 代表 7 天以前修改,-1 代表 24 小时以内修改)
find /data/logs -name "*.log" -mtime +302. 查找后联动处理(-exec 与 xargs)
# 场景一:使用 -exec 删除 30 天前的旧日志({} 代表匹配到的文件名,\; 代表命令结束)
find /data/logs -name "*.log" -mtime +30 -exec rm -f {} \;
# 场景二:配合 xargs(推荐!性能优于 -exec,因为 xargs 会分批批量传递参数,减少进程 fork 次数)
find /data/logs -name "*.log" -mtime +30 | xargs rm -f3. which vs whereis
which python3:仅在系统的环境变量$PATH路径中查找可执行程序的绝对路径;whereis nginx:不仅查找二进制可执行文件,还会搜索相关的源码及 man 手册帮助文档位置。
六、归档与压缩解压:tar 与 zip
在 Linux 中,“打包(归档)”与“压缩”是两步概念,而 tar 通过参数将两者统一:
1. tar 命令经典口诀
| 操作 | 完整命令 | 参数速记拆解 |
|---|---|---|
解压 .tar.gz | tar -zxvf archive.tar.gz -C /target/dir | z (gzip), x (extract 解包), v (verbose 过程), f (file 指定文件) |
打包压缩为 .tar.gz | tar -zcvf archive.tar.gz /path/to/folder | z (gzip), c (create 创建), v (verbose 过程), f (file 指定文件) |
| 查看压缩包内目录不解压 | tar -ztvf archive.tar.gz | t (list 查看列表) |
解压 .tar.bz2 | tar -jxvf archive.tar.bz2 | j 代表 bzip2 解压缩 |
2. zip 与 unzip
# 解压到指定目录
unzip -q project.zip -d /data/project/
# 递归压缩目录为 zip 包(-r 递归,-q 静默)
zip -rq backup.zip /data/project/七、高频面试追问
-
线上生产机器有一个 10GB 的大日志文件,你想排查里面的错误信息,应该怎么做?
- 绝不能做的事:严禁直接执行
cat app.log、vim app.log或nano app.log。这会耗尽终端缓冲区,甚至直接占满机器内存导致 OOM。 - 正确做法:
- 若只需看最后部分报错:使用
tail -n 200 app.log; - 若需要交互式翻页和关键字搜索:使用
less app.log,通过/Error搜索; - 若明确知道关键字:使用
grep -n -C 5 "NullPointerException" app.log | head -n 50截取分析。
- 若只需看最后部分报错:使用
- 绝不能做的事:严禁直接执行
-
硬链接和软链接在底层文件系统结构(inode)上有什么本质区别?
- 硬链接与原文件具有完全相同的 inode 编号,本质上只是目录结构中对该 inode 的新增加的一条“映射记录(引用计数加 1)”。删除原文件时,数据块并不会丢失,只要硬链接还存在,文件依然可读写。硬链接不能跨文件系统,也不能链接目录;
- 软链接拥有独立的全新 inode,数据块中只记录目标文件的“绝对/相对路径文本”。删除原文件后软链接立即失效(断链)。软链接可以跨文件系统,并能链接目录。
-
find ... | xargs rm和find ... -exec rm {} \;有什么区别?为什么生产更推荐xargs?-exec方式是每匹配到一个文件,就会重新 fork 一个独立的rm子进程去删除它。如果有 10 万个文件,就会创建 10 万次子进程,严重消耗 CPU 与系统进程表资源;xargs则是将查找到的文件列表按批次合并为参数(如rm -f file1 file2 file3 ...),通常仅需唤醒几个进程即可批处理完毕,吞吐效率高出数倍。