suppress stderr messages in a bash script

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…)

Asked By: fearless_fool

||

According to this you could do something like following:

#!/bin/bash
exec 2>/dev/null
ls -al test
Answered By: UVV

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.

Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.