Linux Bash shell 脚本中的 IO 重定向没有重新创建移动/删除的文件?

anc*_*mon 5 linux bash stdout stderr io-redirection

我对 Linux 上的 shell 编程很陌生,在我的 Linux 实例中,我正在按照以下方式将程序的 stdout 和 stderr 重定向到两个文件并在后台运行它

myprog > run.log 2>> err.log &
Run Code Online (Sandbox Code Playgroud)

这很好用,我得到了我想要的行为

现在有另一个后台进程监视 run.log 和 err.log,如果日志文件增长超过某个阈值,并将它们移动到其他文件名。

例如 mv err.log err[date-time].log

我的期望是在此文件移动发生后, err.log 将通过 myprog 输出重定向再次创建,并且新输出将写入该新文件。但是,在我的日志文件监视过程移动文件后,err.log 或 run.log 永远不会再次创建,尽管 myprog 继续运行而没有任何问题。

这是 Linux 中的正常行为吗?如果是,我应该怎么做才能让我的预期行为发挥作用?

Vit*_*tor 6

是的。除非您首先重新打开文件,否则它将继续写入旧文件,即使您无法再访问它。事实上,被删除的文件使用的空间只有在每个进程关闭它后才可用。如果重新打开它是不可能的(即你不能更改可执行文件也不能重新启动它),那么像http://httpd.apache.org/docs/2.4/programs/rotatelogs.html这样的解决方案是你最好的选择。它可以根据文件大小或时间轮换日志,甚至可以在轮换后调用自定义脚本。

用法示例:

myprog | rotatelogs logname.log 50M
Run Code Online (Sandbox Code Playgroud)

这样,只要大小达到 50 兆字节,就会轮换日志。

[编辑:指向更新版本的rotatelogs]