将程序的输出重定向到旋转文件

Alb*_*oss 6 linux bash redirect logrotate

我正在尝试将一个连续运行的程序的输出重定向到一个文件 say error_log.

我正在使用的命令看起来像这样,其中myprogram.sh运行不断生成数据并写入/var/log/httpd/error_log

  • myprogram.sh >> /var/log/httpd/error_log

现在我正在使用logrotate每小时轮换这个文件。我正在使用create命令,logrotate以便它重命名原始文件并创建一个新文件。该logrotate配置的样子

/var/log/httpd/error_log {
# copytruncate
 create
 rotate 4
 dateext
 missingok
 ifempty
 .
 .
 .
}
Run Code Online (Sandbox Code Playgroud)

但这里重定向失败。我想要的是myprogram.sh将数据写入error_log文件,而不管它是否被 logrotate 旋转,显然是写入新生成的error_log文件

任何想法如何使基于重定向工作文件名不是描述

或者

在 bash 中还有其他方法吗?

WPo*_*ier 5

如果我理解你的问题,一个解决方案(没有修改myprogram.sh)可能是:

$ myprogram.sh | while true; do head -10 >> /var/log/httpd/error_log; done
Run Code Online (Sandbox Code Playgroud)

解释:

  • myprogram.sh 写入标准输出
  • 我们while通过管道将此输出重定向到bash 语句|
  • while true是一个永远不会结束的无限循环,即使结束时也不会myprogram.sh破坏管道。
  • 在每个循环head中,调用命令将从管道读取的前 10 行附加到当前/var/log/httpd/error_log文件的末尾(由于 ,这可能与上一个循环不同logrotate)。

(您可以更改每个循环中写入的行数)

另一种方法是:

$ myprogram.sh | while read line; do echo "$line" >> /var/log/httpd/error_log; done
Run Code Online (Sandbox Code Playgroud)
  • 这与第一个非常相似,但是在myprogram.sh结束或关闭它的标准输出时结束循环。
  • 它逐行工作,而不是成组工作。

  • 这将取决于您的需求。假设`myprogram.sh`每秒向stdout写入几MB,那么我发布的任何一个替代方案都不够快并且管道将被阻塞(最大管道的容量大约为~64KB,具体取决于系统),但是如果该程序每秒仅写入几行(日志通常会这样做),那么两种替代方案都应该可以完成工作,您可能不会感觉到它们之间有任何明显的区别。 (2认同)