【问题标题】:Redirecting output of a program to a rotating file将程序的输出重定向到旋转文件
【发布时间】:2017-05-09 11:31:26
【问题描述】:

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

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

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

现在我使用logrotate 每小时轮换这个文件。我在logrotate 中使用create 命令,以便它重命名原始文件并创建一个新文件。 logrotate 配置看起来像

/var/log/httpd/error_log {
# copytruncate
 create
 rotate 4
 dateext
 missingok
 ifempty
 .
 .
 .
}

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

知道如何根据文件名 描述符进行重定向吗?

在 bash 中还有其他方法吗?

【问题讨论】:

  • 我不明白这个问题。当您进行输出重定向时,它使用文件名,而不是描述符。你能展示你的脚本吗?
  • 是的,能否请您也显示一下您使用过的整个logrotate 命令?
  • 为什么不使用 copytruncate,因此 myprogram.sh 可能会继续写入(附加)到前一个日志文件。你不会有 create 的问题(就像 mv)。

标签: linux bash redirect logrotate


【解决方案1】:

如果我理解您的问题,一种解决方案(无需修改 myprogram.sh)可能是:

$ myprogram.sh | while true; do head -10 >> /var/log/httpd/error_log; done

解释:

  • 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
  • 这与第一个非常相似,但是当myprogram.sh 结束或关闭它的标准输出时,这将结束循环。
  • 它逐行而不是成组地工作。

【讨论】:

  • 这种方法是否有明显的减速?读取速度很慢时听到了吗?
  • 这取决于您的需求。假设myprogram.sh 每秒将几 MB 写入标准输出,那么我发布的两个替代方案都不够快并且管道将被阻塞(最大管道的容量约为 ~64KB,具体取决于系统),但如果程序每秒只写几行(日志通常会这样做),那么两种选择都应该完成工作,你可能不会感觉到它们之间有任何明显的区别。
猜你喜欢
  • 2015-06-21
  • 2014-07-01
  • 2016-07-16
  • 2015-04-04
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 2013-10-11
相关资源
最近更新 更多