如何抑制杀死后出现的Terminated
消息
bash脚本中的进程?
我尝试了set +bm
,但这不起作用。
我知道另一种解决方案涉及调用exec 2> /dev/null
,但就是这样
可靠?如何重新设置它以便我可以继续查看stderr?
答案 0 :(得分:118)
要使消息静音,您必须在生成消息时重定向stderr
。由于kill
命令发送信号并且不等待目标进程响应,因此重定向stderr
命令的kill
对您没有好处。 bash builtin wait
专门用于此目的。
这是一个非常简单的示例,可以杀死最新的后台命令。 (Learn more about $! here.)
kill $!
wait $! 2>/dev/null
由于kill
和wait
都接受多个pid,您还可以执行批量处理。这是一个杀死所有后台进程的例子(当然是当前进程/脚本)。
kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null
答案 1 :(得分:16)
简短的回答是,你不能。 Bash始终打印前台作业的状态。监视标志仅适用于后台作业,仅适用于交互式shell,而不适用于脚本。
请参阅jobs.c中的notify_of_job_status()。
正如您所说,您可以重定向,因此标准错误指向/ dev / null,但您会错过任何其他错误消息。您可以通过在运行脚本的子shell中执行重定向来使其成为临时的。这样就留下了原始环境。
(script 2> /dev/null)
将丢失所有错误消息,但只是来自该脚本,而不是来自该shell中运行的任何其他内容。
您可以通过重定向新的文件描述符来保存和恢复标准错误:
exec 3>&2 # 3 is now a copy of 2
exec 2> /dev/null # 2 now points to /dev/null
script # run script with redirected stderr
exec 2>&3 # restore stderr to saved
exec 3>&- # close saved version
但是我不建议这样做 - 第一个的唯一好处是它保存了一个子shell调用,同时更复杂,甚至可能改变脚本的行为,如果脚本改变了文件描述符
修改强>
给出的更合适的答案检查答案答案 2 :(得分:15)
受MarcH’s answer的启发。我正在使用kill -INT
,因为他建议取得一些成功,但我注意到它并没有杀死一些进程。在测试了一些其他信号后,我发现SIGPIPE
也会在没有消息的情况下终止。
kill -PIPE
或只是
kill -13
答案 3 :(得分:8)
解决方案:使用SIGINT(仅适用于非交互式shell)
演示:
cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF
sh silent.sh
答案 4 :(得分:4)
也许通过调用disown
?
答案 5 :(得分:1)
这是我们都在寻找的吗?
不想要:
$ sleep 3 &
[1] 234
<pressing enter a few times....>
$
$
[1]+ Done sleep 3
$
通缉:
$ (set +m; sleep 3 &)
<again, pressing enter several times....>
$
$
$
$
$
如您所见,没有工作结束消息。在bash脚本中也适用于我,也适用于被杀死的后台进程。
'set + m'禁用当前shell的作业控制(请参阅“帮助集”)。因此,如果您在子shell中输入命令(如括号中所示),则不会影响当前shell的作业控制设置。唯一的缺点是,如果要检查它是否已终止,或者评估返回代码,则需要将后台进程的pid恢复到当前shell。
答案 6 :(得分:1)
这也适用于killall(对于喜欢它的人):
killall -s SIGINT (yourprogram)
抑制消息......我在后台模式下运行mpg123。 它只能通过发送ctrl-c(SIGINT)而不是SIGTERM(默认)来静默杀死。
答案 7 :(得分:1)
禁用作业通知的另一种方法是将命令置于sh -c 'cmd &'
构造中。
#!/bin/bash
# ...
pid="`sh -c 'sleep 30 & echo ${!}' | head -1`"
kill "$pid"
# ...
# or put several cmds in sh -c '...' construct
sh -c '
sleep 30 &
pid="${!}"
sleep 5
kill "${pid}"
'
答案 8 :(得分:0)
答案 9 :(得分:0)
在脚本中添加“jobs 2>&1 >/dev/null
”是否成功,不确定它是否会帮助其他人的脚本,但这里有一个示例。
while true; do echo $RANDOM; done | while read line
do
echo Random is $line the last jobid is $(jobs -lp)
jobs 2>&1 >/dev/null
sleep 3
done
答案 10 :(得分:0)
简单:
{ kill $! } 2>/dev/null
优势?可以使用任何信号
例如:
{ kill -9 $PID } 2>/dev/null
答案 11 :(得分:0)
我发现将kill命令放在一个函数中,然后对该函数进行后台处理会抑制终止输出
function killCmd() {
kill $1
}
killCmd $somePID &
答案 12 :(得分:0)
Terminated
由 bash 3.x 和 4.x 的默认信号处理程序记录。只需在子进程的第一个捕获 TERM 信号:
#!/bin/sh
## assume script name is test.sh
foo() {
trap 'exit 0' TERM ## here is the key
while true; do sleep 1; done
}
echo before child
ps aux | grep 'test\.s[h]\|slee[p]'
foo &
pid=$!
sleep 1 # wait trap is done
echo before kill
ps aux | grep 'test\.s[h]\|slee[p]'
kill $pid ## no need to redirect stdin/stderr
sleep 1 # wait kill is done
echo after kill
ps aux | grep 'test\.s[h]\|slee[p]'