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
原文(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