清空文本文件的内容

sos*_*tee 18 command-line

我的主目录中有一个文本文件,它通过 cron 作业定期接收数据。因为 cron 作业提供动态数据,我还想设置一个 cron 作业来清空文件内容(该文件必须仍然存在)。我不需要 cron 帮助,只需要可以帮助清空文件的命令。

Rad*_*anu 29

最简单的方法:

> filename
Run Code Online (Sandbox Code Playgroud)

这是一种不太明显的方式,其他人在 shell 脚本中的可读性可能较低,但这就是您所需要的。

因为>实际上不是一个真正的命令(它是内置的 bash),你不能使用:

sudo > filename
Run Code Online (Sandbox Code Playgroud)

当您对该文件没有权限时。但是你可以使用:

sudo bash -c "> filename"
Run Code Online (Sandbox Code Playgroud)


les*_*ana 23

为此目的创建了一个工具:

truncate -s 0 filename
Run Code Online (Sandbox Code Playgroud)

这将清除内容,但它仍然是同一个文件(inode保持不变)。

假设您使用删除和重新创建文件的简单方法来“清空”一个文件:新文件(通常)会有一个新的 inode。

这个 inode 很重要,因为一些程序“按 inode”持有文件的句柄。即使在您删除并重新创建文件后,这些程序仍将保留带有旧内容的旧文件。该程序通过旧 inode 保存旧文件,而您重新创建的空文件有一个新 inode。

此答案末尾的一些链接指向更多详细信息。


另一种方式,也许更容易记住:

echo -n > filename
Run Code Online (Sandbox Code Playgroud)

这也保持了相同的 inode。

请注意,truncateecho -n都不是由POSIX定义的。

对于 POSIX 合规性使用cat /dev/null

cat /dev/null > filename
Run Code Online (Sandbox Code Playgroud)

还有另一种方式,更晦涩,可能与 shell 无关:

> filename
Run Code Online (Sandbox Code Playgroud)

如果要截断的文件需要 root 权限才能写入,那么以下几行将不会像您预期的那样工作:

# following commands do not work
sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename
Run Code Online (Sandbox Code Playgroud)

这是因为重定向是在执行 sudo 之前由 shell 完成的。这意味着对文件的写访问是使用运行 shell 的用户的权限完成的,而不是由 sudo 授予的权限。

一种解决方法是将重定向推迟到使用 sudo 权限执行的 shell,如下所示:

sudo sh -c "echo -n > filename"
Run Code Online (Sandbox Code Playgroud)

使用truncate您不需要这样的解决方法,因为写访问不是由 shell 完成的,而是truncate由 sudo 使用 sudo 权限执行的。

sudo truncate -s 0 filename
Run Code Online (Sandbox Code Playgroud)

有关即使文件已被删除仍保持文件打开的程序的一些详细信息,您可以阅读以下内容:

  • 也许您在 bash 中启用了 noclobber? (2认同)