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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值