我的主目录中有一个文本文件,它通过 cron 作业定期接收数据。由于 cron 作业提供动态数据,因此我还想设置一个 cron 作业来清空文件内容(该文件必须仍然存在)。我不需要 cron 的帮助,只需要可以帮助清空文件的命令。
答案1
最简单的方法:
> filename
这是一种不太明显的方法,可能其他人用 shell 脚本读起来不太容易,但这就是您所需要的。
因为>
实际上不是一个真正的命令(它是 bash 内置的),所以你不能使用:
sudo > filename
当您没有该文件的权限时。但您可以使用:
sudo bash -c "> filename"
答案2
有一个为此目的而创建的工具:
truncate -s 0 filename
这将清除内容,但它仍然是同一个文件(索引节点保持不变)。
假设您使用删除并重新创建文件的简单方法“清空”一个文件:新文件(通常)将有一个新的 inode。
此 inode 很重要,因为某些程序会“通过 inode”保存文件的句柄。即使您删除并重新创建了文件,这些程序仍会保留包含旧内容的旧文件。程序通过旧 inode 保存旧文件,而您重新创建的空文件则具有新的 inode。
本答案末尾有一些指向更多详细信息的链接。
另一种方法可能更容易记住:
echo -n > filename
这也保留了相同的 inode。
请注意,truncate
和echo -n
均未定义为POSIX。
为了符合 POSIX 规范,请使用cat /dev/null
:
cat /dev/null > filename
还有另一种方法,更加晦涩,并且可能与 shell 无关:
> filename
如果要截断的文件需要 root 权限才能写入,则以下几行将无法按您预期的方式工作:
# following commands do not work
sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename
这是因为重定向是在执行 sudo 之前由 shell 完成的。这意味着对文件的写访问是使用运行 shell 的用户的权限完成的,而不是 sudo 授予的权限。
一种解决方法是将重定向推迟到使用 sudo 权限执行的 shell,如下所示:
sudo sh -c "echo -n > filename"
您不需要truncate
这样的解决方法,因为写访问不是由 shell 完成的,而是由truncate
sudo 使用 sudo 权限执行的。
sudo truncate -s 0 filename
有关程序即使文件已被删除仍保持文件打开的一些详细信息,您可以阅读以下内容:
- https://stackoverflow.com/questions/2028874/what-happens-to-an-open-file-handler-on-linux-if-the-pointed-file-gets-moved-de
- https://serverfault.com/questions/501963/how-to-recover-free-space-on-deleted-files-without-restarting-the-referencing-pr
- https://unix.stackexchange.com/questions/182077/best-way-to-free-disk-space-from-deleted-files-that-are-held-open
- https://stackoverflow.com/questions/51019714/does-recreating-a-file-reuse-the-previous-inode
答案3
要实现此自动化,您可以使用 logrotate。只需为要清空的文件创建一个配置文件,添加其他设置,然后您就可以根据每天选择的标准或当文件大于等时自动清空它。
查看这里如何配置 logrotate: http://linuxcommand.org/man_pages/logrotate8.html
答案4
echo "" > foo_file
这是一种简单的方法,它将替换foo_文件和“”在这种情况下,使其成为空的。
您还可以使用cat /dev/null > foo_file
,它将读取空设备并用任何内容覆盖您的文件。