天天看點

linux shell kill程序,linux-bash:靜默殺死背景功能程序

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