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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/81520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 17:39:12  来源:igfitidea点击:

How to suppress Terminated message after killing in bash?

bashunixshell

提问by user14437

How can you suppress the Terminatedmessage that comes up after you kill a process in a bash script?

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

I tried set +bm, but that doesn't work.

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

I know another solution involves calling exec 2> /dev/null, but is that reliable? How do I reset it back so that I can continue to see stderr?

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

采纳答案by wnoise

The short answer is that you can't. Bash always prints the status of foreground jobs. The monitoring flag only applies for background jobs, and only for interactive shells, not scripts.

简短的回答是你不能。Bash 总是打印前台作业的状态。监控标志仅适用于后台作业,并且仅适用于交互式 shell,而不适用于脚本。

see notify_of_job_status() in jobs.c.

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

As you say, you can redirect so standard error is pointing to /dev/null but then you miss any other error messages. You can make it temporary by doing the redirection in a subshell which runs the script. This leaves the original environment alone.

正如您所说,您可以重定向,因此标准错误指向 /dev/null 但随后您会错过任何其他错误消息。您可以通过在运行脚本的子 shell 中进行重定向来使其临时化。这留下了原始环境。

(script 2> /dev/null)

which will lose all error messages, but just from that script, not from anything else run in that shell.

这将丢失所有错误消息,但只是来自该脚本,而不是来自该 shell 中运行的任何其他内容。

You can save and restore standard error, by redirecting a new filedescriptor to point there:

您可以通过重定向新的文件描述符来保存和恢复标准错误:

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

But I wouldn't recommend this -- the only upside from the first one is that it saves a sub-shell invocation, while being more complicated and, possibly even altering the behavior of the script, if the script alters file descriptors.

但我不推荐这个——第一个的唯一好处是它节省了一个子 shell 调用,同时更复杂,如果脚本改变文件描述符,甚至可能改变脚本的行为。



EDIT:

编辑:

For more appropriate answer check answer given by Mark Edgar

对于更合适的答案,请检查Mark Edgar给出的答案

回答by Mark Edgar

In order to silence the message, you must be redirecting stderrat the time the message is generated. Because the killcommand sends a signal and doesn't wait for the target process to respond, redirecting stderrof the killcommand does you no good. The bash builtin waitwas made specifically for this purpose.

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

Here is very simple example that kills the most recent background command. (Learn more about $! here.)

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

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

Because both killand waitaccept multiple pids, you can also do batch kills. Here is an example that kills all background processes (of the current process/script of course).

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

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

I was led here from bash: silently kill background function process.

我被bash引导到这里:静默杀死后台函数进程

回答by Steven Penny

Inspired by MarcH's answer. I was using kill -INTas he suggests with some success, but I noticed that it was not killing some processes. After testing some other signals I see that SIGPIPEwill kill as well without a message.

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

kill -PIPE

or simply

或者干脆

kill -13

回答by MarcH

Solution: use SIGINT (works only in non-interactive shells)

解决方案:使用 SIGINT(仅适用于非交互式 shell)

Demo:

演示:

cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF

sh silent.sh

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

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

回答by Matthias Kestenholz

Maybe detach the process from the current shell process by calling disown?

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

回答by phily

Another way to disable job notifications is to place your command to be backgrounded in a sh -c 'cmd &'construct.

禁用作业通知的另一种方法是将您的命令置于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}"
'

回答by Ralph

Is this what we are all looking for?

这是我们都在寻找的吗?

Not wanted:

不想要:

$ sleep 3 &
[1] 234
<pressing enter a few times....>
$
$
[1]+  Done                    sleep 3
$

Wanted:

通缉:

$ (set +m; sleep 3 &)
<again, pressing enter several times....>
$
$
$
$
$

As you can see, no job end message. Works for me in bash scripts as well, also for killed background processes.

如您所见,没有作业结束消息。在 bash 脚本中也适用于我,也适用于被杀死的后台进程。

'set +m' disables job control (see 'help set') for the current shell. So if you enter your command in a subshell (as done here in brackets) you will not influence the job control settings of the current shell. Only disadvantage is that you need to get the pid of your background process back to the current shell if you want to check whether it has terminated, or evaluate the return code.

'set +m' 禁用当前 shell 的作业控制(参见 'help set')。因此,如果您在子 shell 中输入命令(如此处在括号中所做的那样),您将不会影响当前 shell 的作业控制设置。唯一的缺点是,如果要检查后台进程是否已终止或评估返回码,则需要将后台进程的 pid 返回到当前 shell。

回答by Coder of Salvation

This also works for killall (for those who prefer it):

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

killall -s SIGINT (yourprogram) 

suppresses the message... I was running mpg123 in background mode. It could only silently be killed by sending a ctrl-c (SIGINT) instead of a SIGTERM (default).

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

回答by J-o-h-n-

Had success with adding 'jobs 2>&1 >/dev/null' to the script, not certain if it will help anyone else's script, but here is a sample.

成功地将“ 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

回答by J-o-h-n-

Simple:

简单的:

{ kill $! } 2>/dev/null

Advantage? can use any signal

优势?可以使用任何信号

ex:

前任:

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