当前位置:首页> 正文

关于unix:在bash中杀死后如何抑制终止消息?

关于unix:在bash中杀死后如何抑制终止消息?

How to suppress Terminated message after killing in bash?

您如何抑制在杀死键盘后出现的Terminated消息
在bash脚本中处理?

我尝试了set +bm,但这不起作用。

我知道另一个解决方案涉及调用exec 2> /dev/null,但这是
可靠? 我如何将其重置,以便继续看到stderr?


为了使消息静音,必须在生成消息时重定向stderr。因为kill命令发送信号并且不等待目标进程响应,所以重定向kill命令的stderr不会对您有帮助。 bash内置的wait专门用于此目的。

这是一个非常简单的示例,它杀死了最新的后台命令。 (在此处了解有关$!的更多信息。)

1
2
kill $!
wait $! 2>/dev/null

因为killwait都接受多个pid,所以您也可以执行批量杀死。这是一个杀死所有后台进程(当然是当前进程/脚本)的示例。

1
2
kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null

我从bash那里被带到这里:默默地杀死后台函数进程。


简短的答案是你不能。 Bash始终打印前台作业的状态。监视标志仅适用于后台作业,并且仅适用于交互式外壳,不适用于脚本。

请参阅Jobs.c中的notify_of_job_status()。

如您所说,您可以重定向以便标准错误指向/ dev / null,但是您会错过任何其他错误消息。您可以通过在运行脚本的子外壳中进行重定向来使其成为临时的。这使原始环境独自存在。

1
(script 2> /dev/null)

这将丢失所有错误消息,但只会丢失该脚本发出的错误消息,而不会丢失该Shell中运行的任何其他消息。

您可以通过重定向新的filedescriptor指向该位置来保存和恢复标准错误:

1
2
3
4
5
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

但是我不建议这样做-从第一个开始的唯一好处就是,它节省了子外壳程序调用,同时更加复杂,并且如果脚本更改了文件描述符,它甚至可以更改脚本的行为。

编辑:

有关更适当的答案,请检查马克·埃德加(Mark Edgar)给出的答案


受MarcH的回答启发。我按照他的建议使用kill -INT取得了一些成功,但是我注意到它并没有杀死某些进程。在测试了一些其他信号之后,我看到SIGPIPE也会在没有消息的情况下终止。

1
kill -PIPE

或简单地

1
kill -13

解决方案:使用SIGINT(仅在非交互式外壳中有效)

演示:

1
2
3
4
5
6
7
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进程分离?


禁用作业通知的另一种方法是将命令置于sh -c 'cmd &'构造的后台。

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/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(对于那些喜欢它的人):

1
killall -s SIGINT (yourprogram)

禁止显示消息...我在后台模式下运行mpg123。
它只能通过发送ctrl-c(SIGINT)而不是SIGTERM(默认值)来静默杀死。


这就是我们所有人想要的吗?

不需要:

1
2
3
4
5
6
7
$ sleep 3 &
[1] 234
[cc lang="bash"]
$
$
[1]+  Done                    sleep 3
$

通缉:

1
2
3
4
5
6
7
$ (set +m; sleep 3 &)

$
$
$
$
$

如您所见,没有作业结束消息。在bash脚本中也对我有用,对于后台进程也是如此。

'set + m'禁用当前shell的作业控制(请参阅"帮助集")。因此,如果您在子外壳程序中输入命令(如括号中所示),则不会影响当前外壳程序的作业控制设置。唯一的缺点是,如果要检查它是否已终止或评估返回代码,则需要将后台进程的pid返回到当前shell。


我发现将kill命令放入函数中,然后使该函数后台运行会抑制终止输出

1
2
3
4
5
function killCmd() {
    kill $1
}

killCmd $somePID &

简单:

1
{ kill $! } 2>/dev/null

优点?可以使用任何信号

例如:

1
{ kill -9 $PID } 2>/dev/null

在脚本中添加" jobs 2>&1 >/dev/null"是否成功,不确定是否会帮助其他人的脚本,但这是一个示例。

1
2
3
4
5
6
    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

disown为我做了完全正确的事情-exec 3>&2有很多原因是有风险的-set + bm似乎在脚本内不起作用,仅在命令提示符下起作用


展开全文阅读

相关内容