我正在编写一个bash脚本,通过SSH使用rsync执行异地备份。我可以将STDOUT发送到记录器,通过
发送日志rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup | logger -i
但我想发送STDERR,所以如果出现问题,例如 offsite 不可用,那么该输出应该发送到记录器并记录下来。
答案 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),你可以执行以下操作:
看起来像这样:
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>&-