将STDERR发送到记录器

时间:2010-03-26 14:47:09

标签: bash stream logging

我正在编写一个bash脚本,通过SSH使用rsync执行异地备份。我可以将STDOUT发送到记录器,通过

发送日志
rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup | logger -i

但我想发送STDERR,所以如果出现问题,例如 offsite 不可用,那么该输出应该发送到记录器并记录下来。

3 个答案:

答案 0 :(得分:6)

您可以通过添加2>&1将STDERR描述符(2)重定向到STDOUT(1),例如:

rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup  2>&1 | logger -i

答案 1 :(得分:6)

如果你想要stderr而不是stdout(而不是stderr AND stdout),你可以执行以下操作:

  1. 打开另一个文件描述符(9)
  2. 将stdout(1)重定向到新文件描述符(9)
  3. 将stderr(2)重定向到stdout(1)
  4. 看起来像这样:

    rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup 9> /dev/null 1>&9 2>&1 | logger -i
    

    或者,您可以使用流程替换:

    logger -i <( rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup > /dev/null )
    

答案 2 :(得分:2)

另一种确保捕获脚本错误以及rsync错误的方法是执行以下操作:

#!/bin/bash

set -eu
set -o pipefail

exec 1>/dev/null 2> >(logger -t "stderr-from-my-script")

: do some interesting things

rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup

: do some other interesting things

现在,将记录写入stderr的所有数据,而不仅仅是来自rsync的数据。但是,在调试时忽略stdout通常是一个坏主意,因为可以在那里记录可能突出错误原因的有用信息。如果你想区分stderr和stdout,只是不要跨越流

exec 1> >(logger -t "stdout-from-my-script") 2> >(logger -t "stderr-from-my-script")

要显式关闭句柄或恢复它们,请考虑以下事项:

exec {OLD_STDOUT}>&1 {OLD_STDERR}>&2 1> >(logger -t "stdout-from-my-script") 2> >(logger -t "stderr-from-my-script")

: Do some interesting things

eval exec 1>&${OLD_STDOUT} 2>&${OLD_STDERR} ${OLD_STDOUT}>&- ${OLD_STDERR}>&-

对于旧版本的bash,你可能需要更加直率:

exec 3>&1 4>&2 1> >(logger -t "stdout-from-my-script") 2> >(logger -t "stderr-from-my-script")

: Do some interesting things

exec 1>&3 2>&4 3>&- 4>&-