11 月 212013
 

原文(source): linux – bash: silently kill background function process – Stack Overflow

I have a bash shell script, in which I launch a background function, say foo(), to display a progress bar for a boring and long command:

foo()
{
    while [ 1 ]
    do
        #massively cool progress bar display code
        sleep 1
    done
}

foo &
foo_pid=$!

boring_and_long_command
kill $foo_pid >/dev/null 2>&1
sleep 10

now, when foo dies, I see the following text:

/home/user/script: line XXX:30290Killed                  foo

This totally destroys the awesomeness of my, otherwise massively cool, progress bar display. How do I get rid of this message?

================================================================

kill $foo_pid
wait $foo_pid 2>/dev/null

BTW, I don’t know about your massively cool progress bar, but have you seen Pipe Viewer (pv)? http://www.ivarch.com/programs/pv.shtml

================================================================

Try to replace your line kill $foo_pid >/dev/null 2>&1 with the line:

(kill $foo_pid 2>&1)>/dev/null

================================================================

This is a solution I came up with for a similar problem (wanted to display a timestamp during long running processes). This implements a killsub function that allows you to kill any subshell quietly as long as you know the pid. Note, that the trap instructions are important to include: in case the script is interrupted, the subshell will not continue to run.

foo()
{
    while [ 1 ]
    do
        #massively cool progress bar display code
        sleep 1
    done
}

#Kills the sub process quietly
function killsub() 
{

    kill -9 ${1} 2>/dev/null
    wait ${1} 2>/dev/null

}

foo &
foo_pid=$!

#Add a trap incase of unexpected interruptions
trap 'killsub ${foo_pid}; exit' INT TERM EXIT

boring_and_long_command

#Kill foo after finished
killsub ${foo_pid}

#Reset trap
trap - INT TERM EXIT

================================================================

This “hack” seems to work:

# Some trickery to hide killed message
exec 3>&2          # 3 is now a copy of 2
exec 2> /dev/null  # 2 now points to /dev/null
kill $foo_pid >/dev/null 2>&1
sleep 1            # sleep to wait for process to die
exec 2>&3          # restore stderr to saved
exec 3>&-          # close saved version

and it was inspired from here. World order has been restored.

================================================================

Add at the start of the function:

trap 'exit 0' TERM

================================================================

Another way to do it:

    func_terminate_service(){

      [[ "$(pidof ${1})" ]] && killall ${1}
      sleep 2
      [[ "$(pidof ${1})" ]] && kill -9 "$(pidof ${1})" 

    }

call it with

    func_terminate_service "firefox"

================================================================

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

#!/bin/bash

foo()
{
   while [ 1 ]
   do
       sleep 1
   done
}

#foo &
#foo_pid=$!

export -f foo
foo_pid=`sh -c 'foo & echo ${!}' | head -1`

# if shell does not support exporting functions (export -f foo)
#arg1='foo() { while [ 1 ]; do sleep 1; done; }'
#foo_pid=`sh -c 'eval "$1"; foo & echo ${!}' _ "$arg1" | head -1`

sleep 3
echo kill ${foo_pid}
kill ${foo_pid}
sleep 3
exit

================================================================

This can be done using ‘wait’ + redirection of wait to /dev/null :

sleep 2&
PID=$!
kill -9 $PID
wait $PID 2>/dev/null
sleep 2
sleep 2
sleep 2

This script will not give the “killed” message:

-bash-4.1$ ./test
-bash-4.1$ 

While, if you try to use something like:

sleep 2&
PID=$!
kill -9 $PID 2>/dev/null
sleep 2
sleep 2
sleep 2

It will output the message:

-bash-4.1$ ./test
./test: line 4:  5520 Killed                  sleep 2
-bash-4.1$

I like this solution much more than using ‘disown’ which may have other implications.Idea source: http://stackoverflow.com/a/5722850/1208218

 

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

CAPTCHA Image
Play CAPTCHA Audio
Reload Image