bash 将 STDERR 发送到记录器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2524089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending STDERR to logger
提问by Gnutt
Im writing a bash-script to perform an offsite backup, using rsync over SSH. I'm able to send STDOUT to logger, for logs via
我正在编写一个 bash 脚本来执行异地备份,使用 rsync over SSH。我可以将 STDOUT 发送到记录器,用于记录通过
rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup | logger -i
But I want to send STDERR instead, so if there is a problem, such as that offsiteis unavailable, that output should be sent to logger and logged.
但是我想改为发送STDERR,因此如果出现问题,例如异地不可用,则应将该输出发送到记录器并记录。
采纳答案by Patrick McMurchie
If you want stderr instead of stdout (rather than stderr AND stdout), you can do the following:
如果您想要 stderr 而不是 stdout(而不是 stderr AND stdout),您可以执行以下操作:
- open another file descriptor (9)
- redirect stdout (1) to the new file descriptor (9)
- redirect stderr (2) to stdout (1)
- 打开另一个文件描述符 (9)
- 将 stdout (1) 重定向到新的文件描述符 (9)
- 将 stderr (2) 重定向到 stdout (1)
Which looks like this:
看起来像这样:
rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup 9> /dev/null 1>&9 2>&1 | logger -i
Alternately, you could employ process substitution:
或者,您可以使用流程替换:
logger -i <( rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup > /dev/null )
回答by David Gelhar
You can redirect the STDERR descriptor (2) to STDOUT (1) by adding 2>&1, for example:
您可以通过添加将 STDERR 描述符 (2) 重定向到 STDOUT (1) 2>&1,例如:
rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ me@offisite:backup 2>&1 | logger -i
回答by Craig
One other way of ensuring your script errors are captured as well as the rsync errors, is to do something like this:
确保捕获脚本错误以及 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
Now, all the data written to stderr will be logged, not just that from rsync. However, ignoring stdoutis typically a bad idea when it comes to debugging, since useful information that could highlight the cause of an error could be logged there. If you want to differentiate between stderr and stdout, just don't cross the streams:
现在,所有写入 stderr 的数据都将被记录,而不仅仅是来自 rsync 的数据。但是,stdout在调试时忽略通常是个坏主意,因为可以在此处记录可以突出显示错误原因的有用信息。如果您想区分 stderr 和 stdout,请不要跨流:
exec 1> >(logger -t "stdout-from-my-script") 2> >(logger -t "stderr-from-my-script")
To explicitly close the handles or restore them, consider the following:
要显式关闭句柄或恢复它们,请考虑以下事项:
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}>&-
For older versions of bash, you might have to be a bit more blunt:
对于较旧版本的 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>&-

