如何在bash中杀死终止消息?
你怎么能抑制在bash脚本中杀死一个进程后出现的Terminated
消息?
我试过set +bm
,但那不行。
我知道另一个解决scheme涉及调用exec 2> /dev/null
,但是可靠? 我如何重置它,以便我可以继续看到stderr?
简短的答案是你不能。 Bash总是打印前台作业的状态。 监视标志仅适用于后台作业,仅适用于交互式shell,而不适用于脚本。
请参阅jobs.c中的notify_of_job_status()。
正如你所说,你可以redirect,所以标准错误指向/ dev / null,但是你错过任何其他错误消息。 您可以通过在运行脚本的子shell中执行redirect来使其成为临时的。 这只留下原始的环境。
(script 2> /dev/null)
这将失去所有的错误信息,但只是从该脚本,而不是从该shell中运行的其他任何东西。
您可以保存并恢复标准错误,方法是redirect一个新的文件描述符以指向:
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
但我不build议这样做 – 唯一的优点是它保存了一个子shell调用,而且更加复杂,如果脚本改变了文件描述符,甚至可能改变脚本的行为。
编辑:
对于由Mark Edgar给出的更合适的答案检查答案
为了使消息无声,消息生成时必须redirectstderr
。 因为kill
命令发送一个信号而不等待目标进程作出响应,所以redirectkill
命令的stderr
是不行的。 bash内buildwait
是专门为此目的而制定的。
这是杀死最近的背景命令的非常简单的例子。 ( 了解更多关于$!的信息。 )
kill $! wait $! 2>/dev/null
因为kill
和wait
接受多个pid,您也可以执行批处理杀死。 这是一个杀死所有后台进程(当然是当前进程/脚本)的例子。
kill $(jobs -rp) wait $(jobs -rp) 2>/dev/null
我从bash被带到这里:默默地杀死后台函数进程 。
受MarcH的回答启发。 正如他所build议的,我正在使用kill -INT
,但是我注意到它并没有杀死一些进程。 在testing了一些其他信号之后,我发现SIGPIPE
也会在没有消息的情况下被杀死。
kill -PIPE
或干脆
kill -13
解决scheme:使用SIGINT(仅在非交互式shell中工作)
演示:
cat > silent.sh <<"EOF" sleep 100 & kill -INT $! sleep 1 EOF sh silent.sh
也许通过调用disown
从当前的shell进程中分离进程?
这是我们都在寻找什么?
不想要:
$ 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的作业控制(请参阅'help set')。 所以,如果你在一个子shell中input你的命令(如括号中所做的那样),你将不会影响当前shell的作业控制设置。 唯一的缺点是,如果你想检查它是否已经终止,或者计算返回代码,你需要把你的后台进程的pid返回到当前的shell。
这也适用于killall(对于那些喜欢它的人):
killall -s SIGINT(你的程序)
压制消息..我在backgroundmode运行mpg123。 它只能通过发送一个ctrl-c(SIGINT)而不是一个SIGTERM(默认)而被默默地杀死。
另一种禁用作业通知的方法是将命令放在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}" '
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
简单:
{杀了$! } 2> / dev / null
优势? 可以使用任何信号
例如:{kill -9 $ PID} 2> / dev / null