how to stop bash from printing alerts?

2

When killing a process with kill -9 $PID &>/dev/null in a script, a message is still printed to the terminal after the next command terminates. How do you stop this behaviour?

For example

while true; do
    /usr/bin/dostuff -a -b -c
    PID=$(pidof -o %PPID /usr/bin/dostuff)
    sleep 1; 
    kill -KILL $PID &>/dev/null
    echo "hello"
done

will print something like

hello
./my-cript.sh: line 12:  7134 Killed
/usr/bin/dostuff -a -b -c

When I only want it to print "hello"

EDIT: The clean solution is to either run the program in a subshell, or disown it.

#SOLUTION
while true; do
    /usr/bin/dostuff -a -b -c &
    disown
    PID=$!
    sleep 1; 
    kill -KILL $PID &>/dev/null
    echo "hello"
done

brice

Posted 2010-02-17T23:32:27.900

Reputation: 2 206

Why are you even running kill in the background. In the normal case, kill will return quickly and not need to be backgrounded. In this case, you are sleeping anyway...so the what's the point? Just remove the '&'. – William Pursell – 2010-02-18T11:40:24.273

1kill isn't being run in the background. &> redirects stdin and stdout – brice – 2010-02-18T15:26:34.153

Answers

4

The output lines aren't redirected to /dev/null because they aren't STDOUT/STDERR from the kill process. They're output from the shell's job control mechanisms.

If you're using bash, you could run a disown immediately after the job invocation:

while true; do
    /usr/bin/dostuff -a -b -c

    ### remove from shell job table
    disown

    PID=$(pidof -o %PPID /usr/bin/dostuff)
    sleep 1; 
    kill -KILL $PID &>/dev/null
    echo "hello"
done

I tested this in bash v3.2.39 on Debian Lenny, with /bin/sleep 10 & in place of the above /usr/bin/dostuff command:

./tmp.sh
hello
hello
hello
hello
^C

quack quixote

Posted 2010-02-17T23:32:27.900

Reputation: 37 382

cheers ~quack! was just what I was looking for. – brice – 2010-02-18T00:02:35.300

2If you run dostuff with a trailing & then you can get its pid as $! (up until you background another process). That will save you the pidof lookup... oh yeah, someone already said this. – dubiousjim – 2010-02-18T00:52:58.727

3

The error redirection is ineffective because this message is not printed by kill; it is printed by the shell when the background job terminates (I assume a & was missing).

You can avoid this by running in a subshell, using parentheses (but be aware of other potential problems):

while true; do
    (
    /usr/bin/dostuff a b c &
    PID=$!
    sleep 1
    kill -9 $PID
    )
    echo hello
done

b0fh

Posted 2010-02-17T23:32:27.900

Reputation: 2 005

some executables may put themselves in the background, thus not need the &. but yes, this is another way to handle the issue. – quack quixote – 2010-02-17T23:58:14.560

Sorry Bofh, I tested ~quack's solution first. It works exactly as expected though! +1 Thank you. – brice – 2010-02-18T00:14:09.187

0

You could do set -b and install a trap on SIGCHLD. I think the default SIGCHLD handler is what will (immediately) print the job status to the terminal when you've set -b. Here you'd be overriding it.

dubiousjim

Posted 2010-02-17T23:32:27.900

Reputation: 1 128

yeah, i was wondering if there was a set option that would control this behavior. it's part of the description for -m (monitor mode) but setting that doesn't seem to help. i wasn't able to get rid of it by trapping SIGCHLD either. (tried trap /bin/true SIGCHLD but maybe that's not enough.) – quack quixote – 2010-02-18T00:29:50.147

right you are, I just tested a bit myself. I guess disowning is the best option then. – dubiousjim – 2010-02-18T00:51:18.713