重定向到日志文件时如何在 stdout 和 stderr 输出前添加时间戳?

问题描述 投票:0回答:4

在 Linux 中,我在 init 脚本 (SysVInit) 中启动一个名为

$cmd
的程序。我已经将
$cmd
的 stdout 和 stderr 重定向到两个不同的日志文件,名为
$stdout_log
$stderr_log
。现在我还想在打印到日志文件中的每一行前面添加一个时间戳。

我尝试编写一个名为 log_pipe 的函数,如下所示:

log_pipe() {
    while read line; do
        echo [$(date +%Y-%m-%d\ %H:%M:%S)] "$line"
    done
}

然后将我的脚本的输出通过管道传输到此函数中,然后将它们重定向到日志文件,如下所示:

$cmd | log_pipe >> "$stdout_log" 2>> "$stderr_log" &

我得到的是一个空的

$stdout.log
(标准输出)应该没问题,因为
$cmd
通常不打印任何内容。以及一个仅包含时间戳但没有错误文本的
$stderr.log
文件。

我的推理错误在哪里?

PS:因为问题存在于 init 脚本中,所以我只想使用基本的 shell 命令,不需要额外的软件包。

shell logging pipe stdout init
4个回答
4
投票

在任何 POSIX shell 中,尝试:

{ cmd | log_pipe >>stdout.log; } 2>&1 | log_pipe >>stderr.log

此外,如果您有 GNU awk(有时称为

gawk
),那么
log_pipe
可以变得更简单、更快:

log_pipe() {  awk '{print strftime("[%Y-%m-%d %H:%M:%S]"),$0}'; }

示例

作为示例,让我们创建命令

cmd
:

cmd() { echo "This is out"; echo "This is err">&2; }

现在,让我们运行命令并查看输出文件:

$ { cmd | log_pipe >>stdout.log; } 2>&1 | log_pipe >>stderr.log
$ cat stdout.log
[2019-07-04 23:42:20] This is out
$ cat stderr.log
[2019-07-04 23:42:20] This is err

问题

cmd | log_pipe >> "$stdout_log" 2>> "$stderr_log"

上面将标准输出从

cmd
重定向到
log_pipe
log_pipe
的stdout被重定向到
$stdout_log
log_pipe
的stderr被重定向到
$stderr_log
问题是
cmd
的stderr永远不会被重定向。直接到终点站。

举个例子,考虑这个

cmd
:

cmd() { echo "This is out"; echo "This is err">&2; }

现在,让我们运行命令:

$ cmd | log_pipe >>stdout.log 2>>stderr.log
This is err

我们可以看到

This is err
没有发送到文件stderr.log。相反,它出现在终端上。
log_pipe
从未见过它。
stderr.log
仅捕获来自
log_pipe
的错误消息。


1
投票

在 Bash 中,您还可以使用进程替换重定向到子 shell:

logger.sh

#!/bin/bash
while read -r line; do
   echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $line"
done

重定向

cmd > >(logger.sh > stdout.log) 2> >(logger.sh > stderr.log)

0
投票

这可行,但我的命令必须在后台运行,因为它位于初始化脚本中,因此我必须这样做:

({ cmd | log_pipe >>stdout.log; } 2>&1 | log_pipe >>stderr.log) &
echo $! > "$pid_file"

对吗?

但是我认为在这种情况下$pid_file中的pid不是$cmd的pid...


0
投票

这是我完成此任务的最简单方法,其中包含时间戳:

{ ./script.sh | ts >>script-stdout.log; } 2>&1 | ts >>script-stderr.log
© www.soinside.com 2019 - 2024. All rights reserved.