Suppress Stderr Messages in Bash Script

bashshell-scriptstderr

Consider the following (slightly silly) script name 'test1.sh':

#/bin/bash
#
sleep 10 &
echo sleep pid = $!
pkill sleep

When I run it, I get not only the output of the echo, but bash's reporting of the death of sleep on stderr:

$ ./test1.sh
sleep pid = 3551
./test1.sh: line 5:  3551 Terminated              sleep 10

In this case, I'd like to suppress the printout to stderr. I know I can do it on the command line, as in:

$ ./test1.sh 2> /dev/null

… but is there a way to suppress it from within the script? (I know I could wrap it in a second script and have the wrapper redirect it, but there must be something easier…)

Best Answer

You're right; pkill isn't generating the message, bash is.  You suggest that

$ ./test1.sh 2> /dev/null

is a possible solution.  As UVV points out, the equivalent action from within the script is

exec 2> /dev/null

This redirects the stderr for the script to /dev/null from this statement until it is changed back.  Clumsy ways of changing it back include

exec 2> /dev/tty

which redirects stderr to the terminal.  This is probably (but not necessarily) where it was originally.

Or

exec 2>&1

which sets stderr to be the same as stdout, and is likely to be wrong.

A more reliable way is

exec 3>&2
exec 2> /dev/null
(do stuff where you don't want to see the stderr.)
exec 2>&3

which saves the original stderr in file descriptor 3, and later restores it.

Other ways to suppress just the announcement of the process death include

(sleep 10 & pkill sleep) 2> /dev/null

and

{ sleep 10 & pkill sleep;} 2> /dev/null

which change the stderr for only the grouped commands.

Related Question