开发者

Sending STDERR to logger

Im writing a bash-script to perform an offsite backup, using rsync over SSH. 开发者_如何学JAVAI'm able to send STDOUT to logger, for logs via

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 offsite is unavailable, that output should be sent to logger and logged.


You can redirect the STDERR descriptor (2) to STDOUT (1) by adding 2>&1, for example:

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


If you want stderr instead of stdout (rather than stderr AND stdout), you can do the following:

  1. open another file descriptor (9)
  2. redirect stdout (1) to the new file descriptor (9)
  3. redirect stderr (2) to 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 )


One other way of ensuring your script errors are captured as well as the rsync errors, is to do something like this:

#!/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 stdout is 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:

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:

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>&-
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜