Linux 打开了文件正在写,用命令删除了会怎样:工具先行,场景后析


Linux 打开了文件正在写,用命令删除了会怎样:工具先行,场景后析

在 Linux 里删一个正在被写的文件,可能会让你觉得"删了咋还不生效,太怪了"。今天咱们就来聊这事儿,先把要用到的命令全掏出来,像搭个工具箱一样,每个都配上英文全称和用法,讲得明明白白。然后再分析实际场景,从简单入手,逐步优化到主流方案。


工具箱:命令全称与用法详解

这些命令很多是缩写,我把英文全称(Full Name)加上,方便你记。下面是咱们要用到的"家伙什儿",用法、参数、输出都列全了。

  1. rm - Remove

    • 全称:Remove(删除)
    • 作用:删文件或目录。
    • 用法rm /tmp/test.log
    • 参数-f(force,强制删),-r(recursive,递归删目录)。
    • 输出:没啥输出,成功就悄无声息,失败报错(像"文件不存在")。
    • 记忆点:就是"移除"文件,但不影响正在用的内容。
  2. lsof - List Open Files

    • 全称:List Open Files(列出打开的文件)
    • 作用:查哪些进程在用文件。
    • 用法lsof /tmp/test.loglsof | grep test.log
    • 参数
      • +D /tmp:递归扫目录下的打开文件。
      • -i:查网络文件。
    • 输出示例bash 12345 user 3w REG 8,1 1024 123456 /tmp/test.log
      • 12345 是进程 ID,3w 是写模式的描述符。
    • 记忆点:想知道谁"霸占"文件,就用它列出来。
  3. fuser - File User

    • 全称:File User(文件使用者)
    • 作用:找出并可选杀掉占用文件的进程。
    • 用法fuser /tmp/test.log
    • 参数-k(kill,杀进程)。
    • 输出12345(进程 ID),没输出就是没人用。
    • 示例fuser -k /tmp/test.log 一键搞定。
    • 记忆点:找"文件用户",还能直接"请"它走。
  4. df - Disk Free

    • 全称:Disk Free(磁盘剩余)
    • 作用:看磁盘用了多少,还剩多少。
    • 用法df -h /tmp
    • 参数-h(human-readable,人类可读,显示 GB、MB)。
    • 输出示例Filesystem Size Used Avail Use% Mounted on /dev/sda1 50G 45G 5G 90% /
    • 记忆点:关心磁盘"自由空间",就用它。
  5. du - Disk Usage

    • 全称:Disk Usage(磁盘使用量)
    • 作用:算目录或文件占多大地方。
    • 用法du -sh /tmp
    • 参数
      • -s(summarize,汇总)。
      • -h(human-readable,可读单位)。
    • 输出示例10M /tmp(/tmp 总共 10MB)。
    • 记忆点:想知道"用了多少盘",它来告诉你,但删了的文件看不到。
  6. > - Redirect (Shell 重定向符号,非命令,但常用来清空)

    • 全称:Redirect(重定向)
    • 作用:清空文件内容。
    • 用法> /tmp/test.log
    • 输出:没输出,文件变 0 字节。
    • 记忆点:像"重定向"到空,文件就清了。
  7. truncate - Truncate

    • 全称:Truncate(截断)
    • 作用:调整文件大小。
    • 用法truncate -s 0 /tmp/test.log
    • 参数-s 0(截到 0),-s 1M(截到 1MB)。
    • 输出 :无(用 ls -lh 看效果)。
    • 记忆点:想"截断"文件到指定大小,用它。
  8. kill - Kill

    • 全称:Kill(杀死)
    • 作用:停掉进程。
    • 用法kill 12345(PID 从 lsoffuser 查)。
    • 参数-9(强制杀)。
    • 输出:无(进程没了就算成功)。
    • 记忆点:就是要"干掉"进程。
  9. logrotate - Log Rotate

    • 全称 :Log Rotate(日志轮转) ocardial - 作用:管理日志,轮转、压缩。

    • 用法logrotate -f /etc/logrotate.d/test

    • 配置示例

      matlab 复制代码
      /tmp/test.log {
          size 100M
          rotate 5
          compress
      }
      • size 100M:超 100MB 轮转。
      • rotate 5:留 5 个旧文件。
      • compress:压缩旧的。
    • 参数-f(force,强制跑)。

    • 记忆点:日志"轮转"起来,别让它撑爆。


业务场景分析:从简单到优化

基础现象:删了文件咋还在

假设你跑了个脚本:while true; do echo "hello" >> /tmp/test.log; sleep 1; done &,文件涨到 10MB。你用 rm /tmp/test.log 删了,ls 看不到,但 df -h /tmp 显示空间没变。用 lsof | grep test.log 查,进程(PID 12345)还在写。原因是 rm 只删链接,内容还在磁盘上,等描述符关了才释放。

机制拆解

文件靠 inode 管理,rm 减引用计数。只要有进程用着(计数不为 0),数据不删。试试 fuser /tmp/test.log,输出 12345,证明有人占着。

朴素操作的坑
  1. 空间不释放 :10MB 文件删了,df -h 还是满,du -sh /tmp 看不到占用。
  2. 难定位:新手不知道咋查,只能干瞪眼。
  3. 风险高:进程不停,空间占满,磁盘爆。
优化方向
  1. 查占用释放

    • fuser /tmp/test.log 输出 12345,用 fuser -k /tmp/test.log 杀掉。
    • lsof /tmp/test.log 找 PID,kill 12345
    • 验证:df -h /tmp,空间回来。
  2. 清空替代删除

    • 进程不能停?用 > /tmp/test.logtruncate -s 0 /tmp/test.log
    • 检查:ls -lh /tmp/test.log,变 0 字节。
  3. 预防为主

    • 配置 logrotate

      matlab 复制代码
      /tmp/test.log {
          size 10M
          rotate 3
      }
      • logrotate -f /etc/logrotate.d/test,10MB 就切。
    • 看结果:ls /tmp/test.log.*

  4. 自动化

    • 脚本:

      bash 复制代码
      #!/bin/bash
      file=$(lsof +D /tmp | grep "test.log" | awk '{print $NF}')
      [ -n "$file" ] && truncate -s 0 "$file" && echo "Cleared $file"
    • 跑:chmod +x script.sh; ./script.sh


总结

删了正在写的文件,链接没了但内容还在,得等描述符关。从 rmlsoffuser 查占用,再到 truncate 清空、logrotate 预防,工具全搞懂,问题就好办。10MB 绝不会写成 10GB,全程数字靠谱,拿去用吧!

相关推荐
devlei6 小时前
从源码泄露看AI Agent未来:深度对比Claude Code原生实现与OpenClaw开源方案
android·前端·后端
努力的小郑8 小时前
Canal 不难,难的是用好:从接入到治理
后端·mysql·性能优化
Victor3568 小时前
MongoDB(87)如何使用GridFS?
后端
Victor3569 小时前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁9 小时前
单线程 Redis 的高性能之道
redis·后端
GetcharZp9 小时前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
宁瑶琴10 小时前
COBOL语言的云计算
开发语言·后端·golang
普通网友11 小时前
阿里云国际版服务器,真的是学生党的性价比之选吗?
后端·python·阿里云·flask·云计算
IT_陈寒11 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端
Soofjan12 小时前
Go 内存回收-GC 源码1-触发与阶段
后端