The following script uses bash parameter expansion to stuff the basename of the script in to $PROG
, and then using process substitution and redirection to send STDOUT
and STDERR
to syslog as well as the console.
#!/bin/bash
PROG="${0##*/}"
exec > >(2>&-;logger -s -t "$PROG[$$]" -p user.info 2>&1) 2> >(logger -s -t "$PROG[$$]" -p user.error)
echo "This message is to standard out (FD1)."
echo "This message is to STANDARD ERROR (FD2)." >&2
ls
ps >&2
As you can see from the example below, STDOUT
and STDERR
are preserved correctly:
nicolaw@tyrion:~ $ ./foo.sh >/dev/null
foo.sh[15840]: This message is to STANDARD ERROR (FD2).
foo.sh[15840]: PID TTY TIME CMD
foo.sh[15840]: 15367 pts/0 00:00:01 bash
foo.sh[15840]: 15840 pts/0 00:00:00 foo.sh
foo.sh[15840]: 15841 pts/0 00:00:00 foo.sh
foo.sh[15840]: 15842 pts/0 00:00:00 foo.sh
foo.sh[15840]: 15844 pts/0 00:00:00 logger
foo.sh[15840]: 15845 pts/0 00:00:00 logger
foo.sh[15840]: 15846 pts/0 00:00:00 ps
nicolaw@tyrion:~ $ ./foo.sh 2>/dev/null
foo.sh[15847]: This message is to standard out (FD1).
foo.sh[15847]: bin
foo.sh[15847]: data
foo.sh[15847]: etc
foo.sh[15847]: foo.sh
foo.sh[15847]: honeypot
foo.sh[15847]: logs
foo.sh[15847]: Maildir
foo.sh[15847]: svn
foo.sh[15847]: webroot
nicolaw@tyrion:~ $
And we can see that syslog has logged this all to disk for us too:
nicolaw@tyrion:~ $ sudo egrep 'foo.sh\[(15840|15847)\]' /var/log/syslog
Mar 14 19:45:40 tyrion foo.sh[15840]: This message is to standard out (FD1).
Mar 14 19:45:40 tyrion foo.sh[15840]: This message is to STANDARD ERROR (FD2).
Mar 14 19:45:40 tyrion foo.sh[15840]: bin
Mar 14 19:45:40 tyrion foo.sh[15840]: data
Mar 14 19:45:40 tyrion foo.sh[15840]: etc
Mar 14 19:45:40 tyrion foo.sh[15840]: foo.sh
Mar 14 19:45:40 tyrion foo.sh[15840]: honeypot
Mar 14 19:45:40 tyrion foo.sh[15840]: logs
Mar 14 19:45:40 tyrion foo.sh[15840]: Maildir
Mar 14 19:45:40 tyrion foo.sh[15840]: svn
Mar 14 19:45:40 tyrion foo.sh[15840]: webroot
Mar 14 19:45:40 tyrion foo.sh[15840]: PID TTY TIME CMD
Mar 14 19:45:40 tyrion foo.sh[15840]: 15367 pts/0 00:00:01 bash
Mar 14 19:45:40 tyrion foo.sh[15840]: 15840 pts/0 00:00:00 foo.sh
Mar 14 19:45:40 tyrion foo.sh[15840]: 15841 pts/0 00:00:00 foo.sh
Mar 14 19:45:40 tyrion foo.sh[15840]: 15842 pts/0 00:00:00 foo.sh
Mar 14 19:45:40 tyrion foo.sh[15840]: 15844 pts/0 00:00:00 logger
Mar 14 19:45:40 tyrion foo.sh[15840]: 15845 pts/0 00:00:00 logger
Mar 14 19:45:40 tyrion foo.sh[15840]: 15846 pts/0 00:00:00 ps
Mar 14 19:45:43 tyrion foo.sh[15847]: This message is to STANDARD ERROR (FD2).
Mar 14 19:45:43 tyrion foo.sh[15847]: This message is to standard out (FD1).
Mar 14 19:45:43 tyrion foo.sh[15847]: bin
Mar 14 19:45:43 tyrion foo.sh[15847]: data
Mar 14 19:45:43 tyrion foo.sh[15847]: etc
Mar 14 19:45:43 tyrion foo.sh[15847]: foo.sh
Mar 14 19:45:43 tyrion foo.sh[15847]: honeypot
Mar 14 19:45:43 tyrion foo.sh[15847]: logs
Mar 14 19:45:43 tyrion foo.sh[15847]: Maildir
Mar 14 19:45:43 tyrion foo.sh[15847]: svn
Mar 14 19:45:43 tyrion foo.sh[15847]: webroot
Mar 14 19:45:43 tyrion foo.sh[15847]: PID TTY TIME CMD
Mar 14 19:45:43 tyrion foo.sh[15847]: 15367 pts/0 00:00:01 bash
Mar 14 19:45:43 tyrion foo.sh[15847]: 15847 pts/0 00:00:00 foo.sh
Mar 14 19:45:43 tyrion foo.sh[15847]: 15848 pts/0 00:00:00 foo.sh
Mar 14 19:45:43 tyrion foo.sh[15847]: 15849 pts/0 00:00:00 foo.sh
Mar 14 19:45:43 tyrion foo.sh[15847]: 15851 pts/0 00:00:00 logger
Mar 14 19:45:43 tyrion foo.sh[15847]: 15852 pts/0 00:00:00 logger
Mar 14 19:45:43 tyrion foo.sh[15847]: 15853 pts/0 00:00:00 ps
nicolaw@tyrion:~ $
If you found this useful, you may want to check out BashScriptDebugSyslog as well.