3

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
3

3 Answers 3

5

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
2
  • cheers ~quack! was just what I was looking for.
    – brice
    Feb 18, 2010 at 0:02
  • 2
    If 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
    Feb 18, 2010 at 0:52
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
2
  • some executables may put themselves in the background, thus not need the &. but yes, this is another way to handle the issue. Feb 17, 2010 at 23:58
  • Sorry Bofh, I tested ~quack's solution first. It works exactly as expected though! +1 Thank you.
    – brice
    Feb 18, 2010 at 0:14
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.

2
  • 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.) Feb 18, 2010 at 0:29
  • right you are, I just tested a bit myself. I guess disowning is the best option then.
    – dubiousjim
    Feb 18, 2010 at 0:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .