如何在bash中杀死后禁止终止消息?

bash unix shell

41466 观看

12回复

1325 作者的声誉

如何抑制Terminated在bash脚本中终止进程后出现的消息?

我试过了set +bm,但那不起作用。

我知道另一个解决方案涉及呼叫exec 2> /dev/null,但是可靠吗?如何重新设置它以便我可以继续看到stderr?

作者: user14437 的来源 发布者: 2008 年 9 月 17 日

回应 (12)


4

2470 作者的声誉

也许通过调用将进程从当前的shell进程中分离出来disown

作者: Matthias Kestenholz 发布者: 17.09.2008 09:44

16

8775 作者的声誉

决定

简短的回答是,你做不到。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调用,而更复杂,甚至可能改变脚本的行为,如果脚本改变了文件描述符。


编辑:

有关Mark Edgar给出的更合适的答案检查答案

作者: wnoise 发布者: 17.09.2008 10:07

0

9 作者的声誉

disown对我来说做对了 - exec 3>&2因为很多原因而有风险 - set + bm似乎不能在脚本内部工作,只能在命令提示符下运行

作者: clemep 发布者: 28.01.2011 09:04

8

12175 作者的声誉

解决方案:使用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

作者: MarcH 发布者: 31.01.2011 09:55

118

3619 作者的声誉

为了使消息静音,您必须stderr 在生成消息时进行重定向。由于该kill命令发送一个信号,并不会等待目标进程作出回应,重定向stderr的的kill命令对你没有好。bash内置wait是专门为此目的而制作的。

这是一个非常简单的示例,可以杀死最新的后台命令。(了解更多关于$!的信息。

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

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

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

我是从bash带到这里的:默默杀死后台功能进程

作者: Mark Edgar 发布者: 19.04.2011 09:22

1

19 作者的声誉

这是我们都在寻找的吗?

不想要的:

$ 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中输入命令(如括号中所示),则不会影响当前shell的作业控制设置。唯一的缺点是,如果要检查它是否已终止,或者需要评估返回代码,则需要将后台进程的pid恢复到当前shell。

作者: Ralph 发布者: 30.08.2012 01:35

1

151 作者的声誉

这也适用于killall(对于喜欢它的人):

killall -s SIGINT (yourprogram) 

抑制消息......我在后台模式下运行mpg123。它只能通过发送ctrl-c(SIGINT)而不是SIGTERM(默认)来无声地被杀死。

作者: Coder of Salvation 发布者: 04.11.2012 09:43

15

1 作者的声誉

灵感来自MarcH的回答。我正在使用,kill -INT因为他建议取得一些成功,但我注意到它并没有杀死一些进程。在测试了一些其他信号之后,我发现在SIGPIPE没有消息的情况下它也会被杀死。

kill -PIPE

或者干脆

kill -13
作者: Steven Penny 发布者: 04.01.2013 06:35

1

11 作者的声誉

禁用作业通知的另一种方法是将命令置于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}"
'
作者: phily 发布者: 08.03.2013 05:49

0

39 作者的声誉

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
作者: J-o-h-n- 发布者: 07.05.2013 04:34

0

0 作者的声誉

简单:

{ kill $! } 2>/dev/null

优点?可以使用任何信号

例如:

{ kill -9 $PID } 2>/dev/null
作者: user2429558 发布者: 23.06.2013 05:31

0

513 作者的声誉

我发现将kill命令放在一个函数中然后对该函数进行后台处理会抑制终止输出

function killCmd() {
    kill $1
}

killCmd $somePID &
作者: Al Joslin 发布者: 10.02.2018 10:15
32x32