题
怎样才能抑制住 Terminated
杀死bash脚本的过程后出现的消息?
我试过 set +bm
, ,但这不起作用。
我知道另一个解决方案涉及调用 exec 2> /dev/null
, ,但这是可靠的吗?如何将其重置回来以便我可以继续看到 stderr?
解决方案
简短的回答是你不能。Bash 总是打印前台作业的状态。监视标志仅适用于后台作业,并且仅适用于交互式 shell,不适用于脚本。
请参阅 jobs.c 中的 notification_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 调用,同时更复杂,如果脚本更改文件描述符,甚至可能会更改脚本的行为。
编辑:
如需更合适的答案,请检查以下给出的答案 马克·埃德加
其他提示
为了使消息静音,您必须重定向 stderr
消息生成时. 。因为 kill
命令发送信号并且不等待目标进程响应,重定向 stderr
的 kill
命令对你没有好处。bash 内置 wait
是专门为此目的而制作的。
这是一个非常简单的示例,它杀死了最近的后台命令。(了解更多关于$!这里。)
kill $!
wait $! 2>/dev/null
因为两者 kill
和 wait
接受多个pid,也可以批量kill。这是一个杀死所有后台进程(当然是当前进程/脚本)的示例。
kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null
我是被带到这里来的 重击:默默杀死后台功能进程.
灵感来自 马克的回答. 。我正在使用 kill -INT
正如他所建议的那样,取得了一些成功,但我注意到它并没有杀死一些进程。在测试了其他一些信号后,我发现 SIGPIPE
没有消息也会杀人。
kill -PIPE
或者简单地
kill -13
解决方案:使用 SIGINT(仅适用于非交互式 shell)
演示:
cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF
sh silent.sh
也许通过调用将进程与当前 shell 进程分离 disown
?
这是我们都在寻找的吗?
不想要的:
$ 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。
禁用作业通知的另一种方法是将命令置于后台 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}"
'
这也适用于killall(对于那些喜欢它的人):
killall -s SIGINT (yourprogram)
压制消息...我在后台模式下运行 mpg123。只能通过发送 ctrl-c (SIGINT) 而不是 SIGTERM(默认)来静默杀死它。
disown 为我做了完全正确的事情 - exec 3>&2 由于很多原因而存在风险 - set +bm 似乎无法在脚本内工作,只能在命令提示符下工作
添加 ' 已成功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
我发现将kill命令放入函数中然后将该函数置于后台会抑制终止输出
function killCmd() {
kill $1
}
killCmd $somePID &
简单的:
{ kill $! } 2>/dev/null
优势?可以使用任何信号
前任:
{ kill -9 $PID } 2>/dev/null