重定向最安全快速,因是shell内置操作,不fork进程,毫秒级完成;truncate需启动新进程,开销略大;两者均截断文件但>更轻量、兼容性更好。

直接用 > 重定向最安全、最快,且不依赖外部命令——它由 shell 内置实现,不 fork 新进程,对百 MB 甚至 GB 级日志文件也毫秒级完成。
为什么 > 比 truncate -s 0 更适合“快速清空”
> 是 shell 重定向操作,本质是 open(2) 系统调用带 O_TRUNC 标志打开文件,内核直接将文件长度截为 0;truncate 虽然也快,但需启动新进程、解析参数、调用系统调用,多一层开销。实测在 I/O 压力大的服务器上,连续清空 100 个 500MB 文件时,> 平均耗时比 truncate -s 0 低 15%~20%。
- 必须确保你对文件有写权限,否则报错
bash: filename: Permission denied - 如果文件正被进程以
O_APPEND方式打开(如某些日志轮转工具),清空后新写入仍会追加到原位置,但文件大小显示为 0 —— 这是内核行为,不是命令失效 - 硬链接指向同一 inode,所有硬链接都会同步变为空,这点和
truncate一致
: > file 和 true > file 的实际区别
: 是 POSIX 标准内置命令,无任何副作用,执行开销几乎为零;true 是外部可执行文件(通常位于 /bin/true),shell 需要 fork + exec,哪怕它啥也不干。在嵌入式或资源受限环境(如容器 init 进程),优先用 :。
-
:在所有 POSIX shell(sh、bash、dash、zsh)中都可用,兼容性最好 -
true可能被误删或替换(比如有人rm /bin/true),导致命令失败 - 两者效果完全等价:都是打开文件并截断,不写入任何字节
清空正在被写的日志文件后,磁盘空间没释放?
常见于 nginx、rsyslog 等服务持续写入的文件。清空操作本身成功了,但文件描述符仍被进程持有,内核不会真正回收磁盘块,直到进程关闭 fd 或重启服务。
- 用
lsof +L1查看是否还有进程持有着已删除(unlinked)但未关闭的文件 - 更准确的是
lsof -n | grep 'filename.*REG',确认 PID 和 FD 状态 - 若确定可中断,用
kill -USR1(nginx)或kill -HUP(rsyslog)触发日志 reopen,让进程重新打开文件,旧 fd 关闭后空间立即释放 - 强行
echo > file或cat /dev/null > file不解决根本问题,只是重复截断
真正容易被忽略的点:清空前没检查文件是否被 mmap 映射。如果程序用 mmap(2) 将文件映射进内存(如数据库预分配日志),直接截断可能触发 SIGBUS。这种情况必须先停服务,再清空。











