清空日志应优先用 > 或 truncate -s 0:> 快速轻量、保留元数据;truncate 对超大文件毫秒级完成且无 i/o;禁用 echo "" >,避免换行符引发轮转异常。

直接清空比删除更安全,只要日志文件仍被进程打开,就该用截断(truncate)或重定向,而不是 rm。
用 > 重定向快速清空单个日志文件
这是最常用也最轻量的方式,Shell 的 > 操作符会把目标文件大小设为 0,同时保留 inode、权限、属主等元数据,正在写入的日志进程完全无感知。
- 必须用
sudo或 root 权限执行,否则可能因权限不足失败 - 不适用于只读文件(如某些 journal 日志),会报
Permission denied - 对几百 MB 级别的文件极快;但遇到几十 GB 的
catalina.out或*-json.log时,底层仍是 write 系统调用,实际耗时略高
示例:sudo >/var/log/nginx/access.log
用 truncate -s 0 处理超大日志文件
当面对 >10GB 的日志(比如 Docker 容器的 *-json.log 或 Tomcat 的 catalina.out),truncate 是更优选择——它直接修改文件系统中的 size 字段,不触发 I/O 写入,毫秒级完成。
-
truncate不依赖 shell 重定向逻辑,行为更确定 - 支持保留部分日志,例如
truncate -s 1M logfile只留最后 1MB(注意:不是“保留末尾 1MB”,而是截断到 1MB 大小) - 若目标文件被硬链接指向,
truncate只影响该路径,不影响其他链接;而>同样只作用于当前路径
示例:sudo truncate -s 0 /var/lib/docker/containers/*/f2a8646430bd*-json.log
别用 echo "" > file 清空日志
这个命令看似简洁,但会在文件里写入一个换行符(\n),导致文件大小变成 1 字节。某些日志轮转工具(如 logrotate)或监控脚本会据此误判“日志非空”,后续轮转可能异常;更糟的是,Java 应用的 FileAppender 在追加模式下可能从这 1 字节处继续写,造成日志错位。
-
echo -n "" > file能避免换行,但依然调用write(),不如>或truncate干净 -
cat /dev/null > file效果等同于>,适合写进脚本增强可读性,但多一次进程 fork 开销
真正该避开的是带内容的 echo 变体,尤其是没加 -n 的。
批量清理时注意路径和权限边界
用 find 批量操作前,先确认范围是否精准。例如 find / -name "*.log" 可能扫到 /proc 下的伪文件或 NFS 挂载点,导致卡顿或报错。
- 优先限定根目录:
find /var/log -type f -name "*.log" - 对 Docker 日志,固定路径更可靠:
find /var/lib/docker/containers -name "*-json.log" - 加
-print0 | xargs -0替代-exec,避免文件名含空格或特殊字符时报错 - 生产环境建议加
--dry-run类似逻辑(手动先ls验证),切勿直接跑rm -rf
真正容易被忽略的是:清空后,原进程仍在往同一个 inode 写,文件描述符未关闭——所以 df 显示磁盘空间不会立刻释放,要等进程主动 lseek 到 EOF 或重启服务才能彻底回收。这时候看 lsof +L1 能发现“已删除但未释放”的句柄。











