linux-bash:靜默殺死背景功能程序
貝殼大師
我有一個bash shell腳本,在其中我啟動一個背景功能,例如foo(),以顯示一個無聊且冗長的指令的進度條:
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
現在,當foo死亡時,我看到以下文本:
/home/user/script: line XXX: 30290 Killed foo
這完全破壞了我本來非常棒的進度條顯示的出色功能。
我如何擺脫此消息?
9個解決方案
60 votes
kill $foo_pid
wait $foo_pid 2>/dev/null
順便說一句,我不知道您的進度欄多麼酷,但是您看過Pipe Viewer(pv)嗎? [http://www.ivarch.com/programs/pv.shtml]
Mark Edgar answered 2019-12-24T04:54:28Z
30 votes
剛遇到這個我自己,并意識到“尋找”是我們想要的。
foo &
foo_pid=$!
disown
boring_and_long_command
kill $foo_pid
sleep 10
正在列印死亡消息,因為該過程仍在受監視的“作業”的外殼清單中。 disown指令将從該清單中删除最近産生的程序,以便殺死它時即使使用SIGKILL(-9)也不會生成任何調試消息。
pix answered 2019-12-24T04:54:52Z
5 votes
這是我針對類似問題提出的解決方案(希望在長時間運作的過程中顯示時間戳)。 這實作了killsub函數,該函數允許您隻要知道pid即可安靜地殺死任何子shell。 請注意,陷阱指令必須包括以下内容:如果腳本被中斷,則子外殼程式将不會繼續運作。
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
bbbco answered 2019-12-24T04:55:13Z
5 votes
嘗試用以下行替換您的行kill $foo_pid >/dev/null 2>&1:
(kill $foo_pid 2>&1) >/dev/null
更新:
由于@ mklement0在他的評論中解釋的原因,此答案不正确:
此答案對背景作業無效的原因是 在kill指令完成後,異步Bash自身, 輸出有關已終止作業的狀态消息,您不能 直接抑制-除非您使用wait,如接受的答案所示。
Sergei Kurenkov answered 2019-12-24T04:55:47Z
3 votes
這種“ hack”似乎有效:
# 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
從這裡得到啟發。 世界秩序已恢複。
rouble answered 2019-12-24T04:56:11Z
2 votes
在函數開始處添加:
trap 'exit 0' TERM
jilles answered 2019-12-24T04:56:31Z
0 votes
另一種方法是:
func_terminate_service(){
[[ "$(pidof ${1})" ]] && killall ${1}
sleep 2
[[ "$(pidof ${1})" ]] && kill -9 "$(pidof ${1})"
}
用它來稱呼它
func_terminate_service "firefox"
Mike Q answered 2019-12-24T04:56:55Z
0 votes
禁用作業通知的另一種方法是将您的指令放置在sh -c 'cmd &'構造中。
#!/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
phily answered 2019-12-24T04:57:15Z
0 votes
您可以先使用set +m來取消抑制。 有關此的更多資訊
AhmadAssaf answered 2019-12-24T04:57:36Z