Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
share|improve this question
1  
    
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 Feb 18 '10 at 11:40
1  
kill isn't being run in the background. &> redirects stdin and stdout –  brice Feb 18 '10 at 15:26

3 Answers 3

up vote 4 down vote accepted

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
share|improve this answer
    
cheers ~quack! was just what I was looking for. –  brice Feb 18 '10 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 '10 at 0:52

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
share|improve this answer
    
some executables may put themselves in the background, thus not need the &. but yes, this is another way to handle the issue. –  quack quixote Feb 17 '10 at 23:58
    
Sorry Bofh, I tested ~quack's solution first. It works exactly as expected though! +1 Thank you. –  brice Feb 18 '10 at 0:14

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.

share|improve this answer
    
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 Feb 18 '10 at 0:29
    
right you are, I just tested a bit myself. I guess disowning is the best option then. –  dubiousjim Feb 18 '10 at 0:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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