在bash/ksh中我们可以为STDERR重定向添加时间戳吗?
例如myscript.sh 2> error.log
我想在日志上写一个时间戳.
如果您正在谈论每一行的最新时间戳,那么您可能希望在实际脚本中执行此操作(但如果您无权更改它,请参阅下面的一个非常好的解决方案).如果您只想在脚本开始编写之前在自己的行上标记日期,我会使用:
( date 1>&2 ; myscript.sh ) 2>error.log
你需要的是通过另一个程序管道stderr的技巧,该程序可以为每一行添加时间戳.你可以用一个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
它只是一个写入stdout
并stderr
具有特定时间间隔的测试程序.
当您运行该命令时,您实际上会被"d to stdout"
写入stderr(但这是您的TTY设备或stdout
您启动时可能出现的任何其他设备).带时间戳的stderr
行将写入所需的文件.
的devscripts
在于Debian/Ubuntu包包含一个调用的脚本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
这是一个使用while read
类似pax的循环的版本,但不需要额外的文件描述符或单独的脚本(尽管你可以使用一个).它使用进程替换:
myscript.sh 2> >( while read line; do echo "$(date): ${line}"; done > error.log )
使用pax predate.sh
:
myscript.sh 2> >( predate.sh > error.log )
ts
来自moreutils包的程序将标准输入管道输出到标准输出,并在每行前面加上时间戳.
为stdout行添加前缀:command | ts
为stdout和stderr添加前缀:command 2>&1 | ts