如何将时间戳添加到 cronjob 输出的行并将 stdout 和 stderr 重定向到不同的进程和/或文件

Posted

技术标签:

【中文标题】如何将时间戳添加到 cronjob 输出的行并将 stdout 和 stderr 重定向到不同的进程和/或文件【英文标题】:How to add timestamps to lines of a cronjob output and redirect stdout and stderr to different processes and/or files 【发布时间】:2022-01-08 23:40:03 【问题描述】:

我已经为此花费了几个小时 - 将时间戳添加到 cronjobs 的输出行并将 stdout 和 stderr 重定向到单独的进程,然后再到单独的文件,偶然发现了几个陷阱。所以,我决定与外面的人分享我的知识,作为食谱。

【问题讨论】:

【参考方案1】:

所以,代码如下,我将进一步解释特殊性:

crontab sample

MAILTO=""

* * * * * ((/home/ilya/stdoutanderr.sh | ts "\%FT\%T\%z:" >> /srv/data/log/ilya-test-crontab-ts/stdout.log) 2>&1 | ts "\%FT\%T\%z:" >> /srv/data/log/ilya-test-crontab-ts/ts-stderr.log) 2>&1 | logger -t CRONOUT

使用 crontab -e 编辑您的 crontab。

首先,MAILTO="" 行用于禁止发送 cron 输出。如果您不阅读这些邮件 - 最好将其隐藏。

然后您会看到 cronjob 的示例,其中 stdoutanderr.sh 是 cronjob 本身,其余部分用于时间戳、分别记录 stderr 和 stdout 并将命令本身的任何错误输出到 syslog。

stdoutanderr.sh

#!/bin/bash
echo "Sample stdout at " $(date)
echo "Sample stderr at " $(date) >&2

如您所见,示例作业只是将一行输出到 stderr,另一行输出到 stdout,这里没什么特别的。

ts 是来自moreutils 包的实用程序,您应该安装它以使用这种方法(或者您可以将其模拟为一个函数 - 网络中有示例),作业的标准输出通过管道传输到然后附加到指定的文件中。所有这些都发生在括号中,所以在括号的输出中我们只有标准错误。

这是我不知道的第一个棘手部分 - 必须另外在 cronjob 命令行中转义 % 符号,否则该行的其余部分将变成命令的输入,所以充其量它不会t 按预期运行。如您所见 - ts 格式中的 % 符号前面有一个反斜杠。

否则,时间的格式被证明是健壮且信息丰富的,并变成以下:

2021-12-02T12:25:01+0000: Sample stdout at  Thu Dec 2 12:25:01 UTC 2021

您可以使用该格式并添加亚秒级时间分辨率,或者您需要的任何东西。请记住在 cron 中转义百分比符号。

然后为了方便起见,我们将 stderr 重定向到 stdout 以将其通过管道传递到另一个 ts 调用并附加到另一个文件。这是通过重定向2>&1 实现的。但请注意,crontab 使用 dash 而不是 bash 运行,|& 无法按预期工作,因此请使用长重定向。

然后外括号被关闭,剩下的输出(只有在破折号无法处理命令时才应该存在)将登陆到CRONOUT标签下的cron.log或syslog。不过,还没有测试过这一段。如果您启用了邮件和/或其他方式的 crontab 日志记录 - 您可能不需要这个。

玩得开心!

【讨论】:

以上是关于如何将时间戳添加到 cronjob 输出的行并将 stdout 和 stderr 重定向到不同的进程和/或文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 cron 为日志输出条目添加时间戳?

将新行追加到 cronjob 的输出日志

如何将 pandas 时间戳添加到数据帧 post read_csv

想要将时间戳添加到中心对齐文本视图,并将标签调整为右对齐

将 2 个月添加到当前时间戳

如何计算熊猫数据框中每组的行数并将其添加到原始数据中