Reputation: 6391
I'm trying to take stderr
from a command and redirect it to the logger -s
command (which writes its input to syslog
and the -s
option sends a copy of the input to logger
's standard error) and then finally to a file like this:
#!/bin/bash
ping foobar 2> logger -s 2>> ~/mylog.log
Unfortunately, this creates a logger
file and a mylog.log
file. So I'm assuming the initial 2>
creates a logger
file and then the 2>>
creates a new mylog.log
file.
Is there anyway to redirect stderr
to the logger
command?
EDIT
I'm trying to avoid using |
because I want to use the redirection in if
tests as well.
I also tried this way:
ping foobar 2> $(logger -s 2>> ~/mylog.log)
And that didn't work either.
Upvotes: 2
Views: 5900
Reputation: 755104
Given the manual page for logger, you were looking for bash
's process substitution and:
ping foobar 2> >(logger -s 2>> ~/mylog.log)
This runs ping foobar
with standard error going to the process logger -s
via process substitution. The logger
process writes the information to syslog
(the primary purpose of logger
) and also writes the output to standard error (the -s
option). The second I/O redirection appends the standard error from logger
to the file ~/mylog.log
.
The return status of the command is the return status from ping
. This avoids pipes, so you can use the command as written in if
tests, etc.
Upvotes: 7
Reputation: 2930
You can't normally redirect to multiple files. That's what tee
is for. Also, if you're gonna use tee
you need to use a pipe.
ping foobar 2>&1 >/dev/null | tee -a ~/mylog.log | logger
This redirects stderr to stdout and then stdout to /dev/null. tee
appends its input to file ~/mylog.log
(-a
is for append) and also copies it to output, which is then piped to logger
.
If you want to use any resulting complex command in an if test you can put the command in a function. You can use bash's $PIPESTATUS
to check each exit status in the pipe (and return it from the function):
function bla {
ping | successful_cmd # ... or whatever
[ 0 -eq ${PIPESTATUS[0]} ] # return 0 (true) if the exit status of ping was 0 (true)
}
The return status of the function will be the the return status of the last command executed. You can use the function like this:
if bla; then echo true; else echo false; fi
# or
bla && echo success
Upvotes: 1
Reputation: 1863
If you only want stderr...
ping foobar 3>&1 1>&2 2>&3 | logger >> ~/mylog.log
This should swap sderr and stdout.
Upvotes: 2