82

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

5
  • did you try adding the redirect 2> /dev/null after the pkill sleep ?
    – rahul
    Feb 14, 2015 at 6:22
  • 1
    @rahul: yes I did -- pkill isn't generating the message, bash is. Feb 14, 2015 at 6:23
  • I used kill instead of pkill and do not get the stderr. strange..
    – rahul
    Feb 14, 2015 at 6:32
  • @rahul: could it be a built in vs non-built in thing? Did you try it with pkill as well? Feb 14, 2015 at 6:38
  • yes, i believe it is. I get the same error with pkill, but not with kill. While using kill, i used the pid instead of the proc name.
    – rahul
    Feb 14, 2015 at 7:12

2 Answers 2

122

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.

3
  • Are there any dangers associated with saving stdin and stderr to new file descriptors, sending the original descriptors to /dev/null and then restoring them? Sep 15, 2017 at 18:37
  • Well, I suppose that, if you ran a program that (unbeknownst to you) wrote to file descriptor 3 (or 4), that operation would fail under normal circumstances.  But the program could be written to ignore the failure and carry on without reporting it; then you’d never know.  But if your file descriptor 1 (or 2) was “parked” on file descriptor 3 (or 4), then that program would suddenly be writing to your script’s stdout or stderr.  But that’s a very contrived example, and still minimal danger.   Did you have something in mind? Sep 15, 2017 at 18:49
  • 1
    FWIW, I favor Scott's grouped command approach, i.e. { sleep 10 & pkill sleep;} 2> /dev/null Sep 10, 2019 at 21:01
13

According to this you could do something like following:

#!/bin/bash
exec 2>/dev/null
ls -al test
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.