如何在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 

因为killwait接受多个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 

http://thread.gmane.org/gmane.comp.shells.bash.bugs/15798

也许通过调用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