怎样才能抑制住 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 命令发送信号并且不等待目标进程响应,重定向 stderrkill 命令对你没有好处。bash 内置 wait 是专门为此目的而制作的。

这是一个非常简单的示例,它杀死了最近的后台命令。(了解更多关于$!这里。)

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

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

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

也许通过调用将进程与当前 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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top