如何将时间戳添加到STDERR重定向

在bash / ksh中,我们可以添加时间戳到STDERR重定向吗?

例如myscript.sh 2> error.log

我想获得写在日志上的时间戳。


如果您正在讨论每行最新的时间戳,那么您可能希望在您的实际脚本中执行此操作(但如果您无权更改它,请参阅下面的解决方案)。 如果你只想在你的脚本开始写之前在自己的行上设置一个标记日期,我会使用:

( date 1>&2 ; myscript.sh ) 2>error.log

你需要的是通过另一个可以为每行添加时间戳的程序来管理标准错误。 你可以用C程序来做到这一点,但是使用bash方式更加迂回。

首先,创建一个将时间戳添加到每行(称为predate.sh )的脚本:

#!/bin/bash
while read line ; do
    echo "$(date): ${line}"
done

例如:

( echo a ; sleep 5 ; echo b ; sleep 2 ; echo c ) | ./predate.sh

生产:

Fri Oct  2 12:31:39 WAST 2009: a
Fri Oct  2 12:31:44 WAST 2009: b
Fri Oct  2 12:31:46 WAST 2009: c

然后你需要另一个可以交换stdout和stderr的技巧,这里有个小怪物:

( myscript.sh 3>&1 1>&2- 2>&3- )

然后,通过对stdout进行时间戳并将其重定向到您的文件,将两个技巧结合起来很简单:

( myscript.sh 3>&1 1>&2- 2>&3- ) | ./predate.sh >error.log

以下成绩单显示了这一行动:

pax> cat predate.sh
    #!/bin/bash
    while read line ; do
        echo "$(date): ${line}"
    done
pax> cat tstdate.sh
    #!/bin/bash
    echo a to stderr then wait five seconds 1>&2
    sleep 5
    echo b to stderr then wait two seconds 1>&2
    sleep 2
    echo c to stderr 1>&2
    echo d to stdout
pax> ( ( ./tstdate.sh ) 3>&1 1>&2- 2>&3- ) | ./predate.sh >error.log
    d to stdout
pax> cat error.log
    Fri Oct  2 12:49:40 WAST 2009: a to stderr then wait five seconds
    Fri Oct  2 12:49:45 WAST 2009: b to stderr then wait two seconds
    Fri Oct  2 12:49:47 WAST 2009: c to stderr

如前所述, predate.sh会在每行的前面添加一个时间戳,而tstdate.sh只是一个测试程序,用于写入具有特定时间间隔的stdoutstderr

当你运行这个命令时,你实际上会得到写入stderr的"d to stdout" (但这是你的TTY设备或者其他任何stdout启动)。 时间戳stderr行被写入您想要的文件。


Debian / Ubuntu中的devscripts包含一个名为annotate-output的脚本,它可以执行此操作(对于stdout和stderr)。

$ annotate-output make
21:41:21 I: Started make
21:41:21 O: gcc -Wall program.c
21:43:18 E: program.c: Couldn't compile, and took me ages to find out
21:43:19 E: collect2: ld returned 1 exit status
21:43:19 E: make: *** [all] Error 1
21:43:19 I: Finished with exitcode 2

这是一个使用像pax一样的while read循环while read的版本,但不需要额外的文件描述符或单独的脚本(尽管您可以使用一个)。 它使用进程替换:

myscript.sh 2> >( while read line; do echo "$(date): ${line}"; done > error.log )

使用pax的 predate.sh

myscript.sh 2> >( predate.sh > error.log )
链接地址: http://www.djcxy.com/p/25601.html

上一篇: How to add timestamp to STDERR redirection

下一篇: How to Log?