Suppress Notice of Forked Command Being Killed

Let’s suppose I have a bash script (foo.sh) that in a very simplified form, looks like the following:

echo "hello"
sleep 100 &
ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9
echo "bye"

The third line imitates pkill, which I don’t have by default on Mac OS X, but you can think of it as the same as pkill. However, when I run this script, I get the following output:

hello
foo: line 4: 54851 Killed                  sleep 100
bye

How do I suppress the line in the middle so that all I see is hello and bye?

7 thoughts on “Suppress Notice of Forked Command Being Killed

  1. user

    The message is real. The code killed the grep process as well.

    Run ps ax | grep sleep and you should see your grep process on the list.

    What I usually do in this case is ps ax | grep sleep | grep -v grep

    EDIT: This is an answer to older form of question where author omitted the exclusion of grep for the kill sequence. I hope I still get some rep for answering the first half.

    Reply
  2. user

    How about disown? This mostly works for me on Bash on Linux.

    echo "hello"
    sleep 100 &
    disown
    ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9
    echo "bye"
    

    Edit: Matched the poster’s code better.

    Reply
  3. user

    Have you tried to deactivate job control? It’s a non-interactive shell, so I would guess it’s off by default, but it does not hurt to try… It’s regulated by the -m (monitor) shell variable.

    Reply
  4. user

    While disown may have the side effect of silencing the message; this is how you start the process in a way that the message is truly silenced without having to give up job control of the process.

    { command & } 2>/dev/null
    

    If you still want the command’s own stderr (just silencing the shell’s message on stderr) you’ll need to send the process’ stderr to the real stderr:

    { command 2>&3 & } 3>&2 2>/dev/null
    

    To learn about how redirection works:

    And by the way; don’t use kill -9.

    I also feel obligated to comment on your:

    ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9
    

    This will scortch the eyes of any UNIX/Linux user with a clue. Moreover, every time you parse ps, a fairy dies. Do this:

    kill $!
    

    Even tools such as pgrep are essentially broken by design. While they do a better job of matching processes, the fundamental flaws are still there:

    • Race: By the time you get a PID output and parse it back in and use it for something else, the PID might already have disappeared or even replaced by a completely unrelated process.
    • Responsibility: In the UNIX process model, it is the responsibility of a parent to manage its child, nobody else should. A parent should keep its child’s PID if it wants to be able to signal it and only the parent can reliably do so. UNIX kernels have been designed with the assumption that user programs will adhere to this pattern, not violate it.
    Reply
  5. user

    Yet another way to disable job termination messages is to put your command to be backgrounded in a sh -c 'cmd &' construct.

    And as already pointed out, there is no need to imitate pkill; you may store the value of $! in another variable instead.

    echo "hello"
    sleep_pid=`sh -c 'sleep 30 & echo ${!}' | head -1`
    #sleep_pid=`sh -c '(exec 1>&-; exec sleep 30) & echo ${!}'`
    echo kill $sleep_pid
    kill $sleep_pid
    echo "bye"
    
    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *