bash 我应该以什么顺序向正常关闭进程发送信号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/690415/
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
In what order should I send signals to gracefully shutdown processes?
提问by system PAUSE
In a commenton this answerof another question, the commenter says:
don't use kill -9 unless absolutely necessary! SIGKILL can't be trapped so the killed program can't run any shutdown routines to e.g. erase temporary files. First try HUP (1), then INT (2), then QUIT (3)
除非绝对必要,否则不要使用 kill -9 !SIGKILL 不能被捕获,因此被杀死的程序不能运行任何关闭例程来例如擦除临时文件。首先尝试 HUP (1),然后是 INT (2),然后是 QUIT (3)
I agree in principle about SIGKILL
, but the rest is news to me. Given that the default signal sent by kill
is SIGTERM
, I would expect it is the most-commonly expected signal for graceful shutdown of an arbitrary process. Also, I have seen SIGHUP
used for non-terminating reasons, such as telling a daemon "re-read your config file." And it seems to me that SIGINT
(the same interrupt you'd typically get with Ctrl-C, right?) isn't as widely supported as it ought to be, or terminates rather ungracefully.
我原则上同意SIGKILL
,但其余的对我来说是新闻。鉴于发送的默认信号kill
是SIGTERM
,我希望它是正常关闭任意进程的最常见的预期信号。此外,我已经看到SIGHUP
用于非终止原因,例如告诉守护程序“重新读取您的配置文件”。而且在我看来SIGINT
(使用 Ctrl-C 通常会得到相同的中断,对吧?)没有得到应有的广泛支持,或者终止得相当不雅。
Given that SIGKILL
is a last resort — Which signals, and in what order, should you send to an arbitrary process, in order to shut it down as gracefully as possible?
鉴于这SIGKILL
是最后的手段——你应该向任意进程发送哪些信号,以什么顺序发送,以便尽可能优雅地关闭它?
Please substantiate your answers with supporting facts (beyond personal preference or opinion) or references, if you can.
如果可以,请用支持性事实(超出个人偏好或意见)或参考来证实您的答案。
Note: I am particularly interested in best practices that include consideration of bash/Cygwin.
注意:我对包括考虑 bash/Cygwin 的最佳实践特别感兴趣。
Edit:So far, nobody seems to mention INT or QUIT, and there's limited mention of HUP. Is there any reason to include these in an orderly process-killing?
编辑:到目前为止,似乎没有人提到 INT 或 QUIT,而且很少提到 HUP。是否有任何理由将这些包含在有序的进程终止中?
回答by lhunath
SIGTERM tells an application to terminate.The other signals tell the application other things which are unrelated to shutdown but may sometimes have the same result. Don't use those. If you want an application to shut down, tell it to. Don't give it misleading signals.
SIGTERM 告诉应用程序终止。其他信号告诉应用程序其他与关闭无关的事情,但有时可能会产生相同的结果。不要用那些。如果您希望应用程序关闭,请告诉它。不要给它误导性的信号。
Some people believe the smart standard way of terminating a process is by sending it a slew of signals, such as HUP, INT, TERM and finally KILL. This is ridiculous. The right signal for termination is SIGTERM and if SIGTERM doesn't terminate the process instantly, as you might prefer, it's because the application has chosen to handle the signal. Which means it has a very good reason to not terminate immediately: It's got cleanup work to do. If you interrupt that cleanup work with other signals, there's no telling what data from memory it hasn't yet saved to disk, what client applications are left hanging or whether you're interrupting it "mid-sentence" which is effectively data corruption.
有些人认为终止进程的明智标准方法是向它发送一系列信号,例如 HUP、INT、TERM 和最终 KILL。这是荒唐的。终止的正确信号是 SIGTERM,如果 SIGTERM 没有立即终止进程,就像您可能喜欢的那样,那是因为应用程序已选择处理该信号。这意味着它有一个很好的理由不立即终止:它有清理工作要做。如果您使用其他信号中断清理工作,则无法知道内存中的哪些数据尚未保存到磁盘,哪些客户端应用程序仍处于挂起状态,或者您是否在“句子中间”中断它,这实际上是数据损坏。
For more information on what the real meaning of the signals is, see sigaction(2). Don't confuse "Default Action" with "Description", they are not the same thing.
有关信号真正含义的更多信息,请参阅 sigaction(2)。不要将“默认操作”与“描述”混淆,它们不是一回事。
SIGINT is used to signal an interactive "keyboard interrupt" of the process. Some programs may handle the situation in a special way for the purpose of terminal users.
SIGINT 用于发出进程的交互式“键盘中断”信号。为了终端用户的目的,一些程序可能会以特殊的方式处理这种情况。
SIGHUP is used to signal that the terminal has disappeared and is no longer looking at the process. That is all. Some processes choose to shut down in response, generally because their operation makes no sense without a terminal, some choose to do other things such as recheck configuration files.
SIGHUP 用于表示终端已经消失并且不再查看进程。就这些。有些进程选择关闭响应,一般是因为没有终端他们的操作没有意义,有些则选择做其他事情,比如重新检查配置文件。
SIGKILL is used to forcefully remove the process from the kernel. It is special in the sense that it's not actually a signal to the process but rather gets interpreted by the kernel directly.
SIGKILL 用于从内核中强行删除进程。它的特殊之处在于它实际上不是进程的信号,而是直接由内核解释。
Don't send SIGKILL.SIGKILL should certainly never be sent by scripts. If the application handles the SIGTERM, it can take it a second to cleanup, it can take a minute, it can take an hour. Depending on what the application has to get done before it's ready to end. Any logic that "assumes" an application's cleanup sequence has taken long enough and needs to be shortcut or SIGKILLed after X seconds is just plain wrong.
不要发送 SIGKILL。SIGKILL 绝对不应该由脚本发送。如果应用程序处理 SIGTERM,则清理可能需要一秒钟,可能需要一分钟,也可能需要一个小时。取决于应用程序在准备结束之前必须完成的工作。任何“假定”应用程序的清理序列已经花费了足够长的时间并且需要在 X 秒后成为快捷方式或 SIGKILLed 的任何逻辑都是完全错误的。
The only reason why an application would needa SIGKILL to terminate, is if something bugged out during its cleanup sequence. In which case you can open a terminal and SIGKILL it manually. Aside from that, the only one other reason why you'd SIGKILL something is because you WANTto prevent it from cleaning itself up.
应用程序需要SIGKILL 来终止的唯一原因是,如果在其清理过程中出现问题。在这种情况下,您可以打开终端并手动对其进行 SIGKILL。除此之外,唯一的其他原因,为什么你会SIGKILL东西是因为你WANT,以防止其自我整顿。
Even though half the world blindly sends SIGKILL after 5 seconds it's still horribly wrong thing to do.
尽管世界上有一半人在 5 秒后盲目地发送了 SIGKILL,但这仍然是非常错误的做法。
回答by Dr Beco
Short Answer: Send SIGTERM
, 30 seconds later, SIGKILL
. That is, send SIGTERM
, wait a bit (it may vary from program to program, you may know your system better, but 5 to 30 seconds is enough. When shutting down a machine, you may see it automatically waiting up to 1'30s. Why the hurry, after all?), then send SIGKILL
.
简答:发送SIGTERM
,30 秒后,SIGKILL
。即发送SIGTERM
,稍等(可能因程序而异,您可能更了解您的系统,但 5 到 30 秒就足够了。关闭机器时,您可能会看到它自动等待长达 1'30 秒。毕竟为什么要着急?),然后发送SIGKILL
.
Reasonable Answer: SIGTERM
, SIGINT
, SIGKILL
This is more than enough. The process will veryprobably terminate before SIGKILL
.
合理回答:SIGTERM
, SIGINT
,SIGKILL
这已经绰绰有余了。该过程很可能会在 之前终止SIGKILL
。
Long Answer: SIGTERM
, SIGINT
, SIGQUIT
, SIGABRT
, SIGKILL
长答案:SIGTERM
, SIGINT
, SIGQUIT
, SIGABRT
,SIGKILL
This is unnecessary, but at least you are not misleading the process regarding your message. All these signals domean you want the process to stop what it is doing and exit.
这是不必要的,但至少您不会误导有关您的消息的过程。所有这些信号确实意味着您希望进程停止正在执行的操作并退出。
No matter what answer you choose from this explanation, keep that in mind!
无论您从这个解释中选择什么答案,请记住这一点!
If you send a signal that means something else, the process may handle it in very different ways (on one hand). On the other hand, if the process doesn't handle the signal, it doesn't matter what you send after all, the process will quit anyway (when the default action is to terminate, of course).
如果您发送的信号具有其他含义,则该过程可能会以非常不同的方式处理它(一方面)。另一方面,如果进程不处理信号,不管你发送什么,进程无论如何都会退出(当默认操作是终止时,当然)。
So, you must think as yourself as a programmer. Would you code a function handler for, lets say, SIGHUP
to quit a program that connects with something, or would you loop it to try to connect again? That is the main question here! That is why it is important to just send signals that mean what you intend.
因此,您必须将自己视为程序员。你会编写一个函数处理程序,让我们说,SIGHUP
退出与某物连接的程序,还是循环它以尝试再次连接?这是这里的主要问题!这就是为什么只发送意味着你想要的信号很重要的原因。
Almost Stupid Long Answer:
几乎愚蠢的长答案:
The table bellow contains the relevant signals, and the default actions in case the program does not handle them.
下表包含相关信号,以及程序不处理它们时的默认操作。
I ordered them in the order I suggest to use (BTW, I suggest you to use the reasonable answer, not this one here), if you really need to try them all (it would be fun to say the table is ordered in terms of the destruction they may cause, but that is not completelytrue).
我按照我建议使用的顺序订购它们(顺便说一句,我建议你使用合理的答案,而不是这里的这个),如果你真的需要尝试所有这些(说桌子是按照它们可能造成的破坏,但这并不完全正确)。
The signals with an asterisk (*) are NOTrecommended. The important thing about these is that you may never know what it is programmed to do. Specially SIGUSR
! It may start the apocalipse (it is a free signal for a programmer do whatever he/she wants!). But, if not handled ORin the unlikely case it is handled to terminate, the program will terminate.
不建议使用带星号 (*) 的信号。关于这些的重要一点是,您可能永远不知道它被编程用来做什么。特别SIGUSR
!它可能会开始世界末日(这是程序员做任何他/她想做的事情的免费信号!)。但是,如果不处理或在不太可能的情况下处理终止,程序将终止。
In the table, the signals with default options to terminate and generate a core dump are left in the end, just before SIGKILL
.
在表中,具有终止和生成核心转储的默认选项的信号最后留在了SIGKILL
.
Signal Value Action Comment
----------------------------------------------------------------------
SIGTERM 15 Term Termination signal
SIGINT 2 Term Famous CONTROL+C interrupt from keyboard
SIGHUP 1 Term Disconnected terminal or parent died
SIGPIPE 13 Term Broken pipe
SIGALRM(*) 14 Term Timer signal from alarm
SIGUSR2(*) 12 Term User-defined signal 2
SIGUSR1(*) 10 Term User-defined signal 1
SIGQUIT 3 Core CONTRL+\ or quit from keyboard
SIGABRT 6 Core Abort signal from abort(3)
SIGSEGV 11 Core Invalid memory reference
SIGILL 4 Core Illegal Instruction
SIGFPE 8 Core Floating point exception
SIGKILL 9 Term Kill signal
Then I would suggest for this almost stupid long answer:
SIGTERM
, SIGINT
, SIGHUP
, SIGPIPE
, SIGQUIT
, SIGABRT
, SIGKILL
然后我会建议这个几乎愚蠢的长答案:
SIGTERM
, SIGINT
, SIGHUP
, SIGPIPE
, SIGQUIT
, SIGABRT
,SIGKILL
And finally, the
最后,
Definitely Stupid Long Long Answer:
绝对愚蠢的长长答案:
Don't try this at home.
不要在家里尝试这个。
SIGTERM
, SIGINT
, SIGHUP
, SIGPIPE
, SIGALRM
, SIGUSR2
, SIGUSR1
, SIGQUIT
, SIGABRT
, SIGSEGV
, SIGILL
, SIGFPE
and if nothing worked, SIGKILL
.
SIGTERM
, SIGINT
, SIGHUP
, SIGPIPE
, SIGALRM
, SIGUSR2
, SIGUSR1
, SIGQUIT
, SIGABRT
, SIGSEGV
, SIGILL
,SIGFPE
如果没有任何效果,SIGKILL
.
SIGUSR2
should be tried before SIGUSR1
because we are better off if the program doesn't handle the signal. And it is much more likely for it to handle SIGUSR1
if it handles just one of them.
SIGUSR2
应该先尝试,SIGUSR1
因为如果程序不处理信号,我们会更好。SIGUSR1
如果它只处理其中之一,它更有可能处理。
BTW, the KILL: it is not wrong to send SIGKILL
to a process, as other answer stated. Well, think what happens when you send a shutdown
command? It will try SIGTERM
and SIGKILL
only. Why do you think that is the case? And why do you need any other signals, if the very shutdown
command uses only these two?
顺便说一句,KILL:SIGKILL
正如其他答案所述,发送到进程并没有错。好吧,想想当你发送shutdown
命令时会发生什么?它会尝试SIGTERM
和SIGKILL
唯一的。你认为为什么会这样?如果这个shutdown
命令只使用这两个信号,为什么还需要任何其他信号?
Now, back to the long answer, this is a nice oneliner:
现在,回到长答案,这是一个不错的单行:
for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done
It sleeps for 30 seconds between signals. Why else would you need a oneliner? ;)
它在信号之间休眠 30 秒。你为什么还需要一个oneliner?;)
Also, recommended: try it with only signals 15 2 9
from the reasonable answer.
另外,建议:仅使用15 2 9
来自合理答案的信号进行尝试。
safety: remove the second echo
when you are ready to go. I call it my dry-run
for onliners. Always use it to test.
安全:echo
当你准备好去的时候取下第二个。我把它称为我dry-run
的onliners。总是用它来测试。
Script killgracefully
脚本杀死优雅
Actually I was so intrigued by this question that I decided to create a small script to do just that. Please, feel free to download (clone) it here:
实际上我对这个问题很感兴趣,所以我决定创建一个小脚本来做到这一点。请随时在此处下载(克隆)它:
GitHub link to Killgracefully repository
Killgracefully 存储库的GitHub 链接
回答by dwc
Typically you'd send SIGTERM
, the default of kill. It's the default for a reason. Only if a program does not shutdown in a reasonable amount of time should you resort to SIGKILL
. But note that with SIGKILL
the program has no possibility to clean things up und data could be corrupted.
通常你会发送SIGTERM
,默认的kill。出于某种原因,这是默认设置。只有当程序没有在合理的时间内关闭时,您才应该求助于SIGKILL
. 但请注意,SIGKILL
该程序无法清理内容,数据可能会损坏。
As for SIGHUP
, HUP
stands for "hang up" and historically meant that the modem disconnected. It's essentially equivalent to SIGTERM
. The reason that daemons sometimes use SIGHUP
to restart or reload config is that daemons detach from any controlling terminals as a daemon doesn't need those and therefore would never receive SIGHUP
, so that signal was considered as "freed up" for general use. Not all daemons use this for reload! The default action for SIGHUP is to terminate and many daemons behave that way! So you can't go blindly sending SIGHUP
s to daemons and expecting them to survive.
至于SIGHUP
,HUP
代表“挂断”,历史上意味着调制解调器断开连接。它本质上等同于SIGTERM
. 守护进程有时用于SIGHUP
重新启动或重新加载配置的原因是守护进程与任何控制终端分离,因为守护进程不需要这些终端,因此永远不会收到SIGHUP
,因此该信号被视为“释放”以供一般使用。并非所有守护进程都使用它来重新加载!SIGHUP 的默认操作是终止,许多守护进程都是这样的!所以你不能盲目地向SIGHUP
守护进程发送s 并期望它们存活。
Edit:SIGINT
is probably inappropriate to terminate a process, as it's normally tied to ^C
or whatever the terminal setting is to interrupt a program. Many programs capture this for their own purposes, so it's common enough for it not to work. SIGQUIT
typically has the default of creating a core dump, and unless you want core files laying around it's not a good candidate, either.
编辑:SIGINT
可能不适合终止进程,因为它通常与^C
或任何终端设置用于中断程序相关联。许多程序出于自己的目的捕获它,因此它无法正常工作是很常见的。SIGQUIT
通常具有创建核心转储的默认设置,除非您想要放置核心文件,否则它也不是一个好的选择。
Summary: if you send SIGTERM
and the program doesn't die within your timeframe then send it SIGKILL
.
总结:如果你发送SIGTERM
并且程序没有在你的时间范围内死亡,那么发送它SIGKILL
。
回答by vartec
SIGTERM
actually means sending an application a message: "would you be so kind and commit suicide". It can be trapped and handled by application to run cleanup and shutdown code.
SIGTERM
实际上意味着向应用程序发送一条消息:“你会如此善良并自杀吗”。它可以被应用程序捕获和处理以运行清理和关闭代码。
SIGKILL
cannot be trapped by application. Application gets killed by OS without any chance for cleanup.
SIGKILL
不能被应用程序困住。应用程序被操作系统杀死而没有任何清理机会。
It's typical to send SIGTERM
first, sleep some time, then send SIGKILL
.
通常先发送SIGTERM
,休眠一段时间,然后发送SIGKILL
。
回答by gbarry
- SIGTERM is equivalent to "clicking the 'X' " in a window.
- SIGTERM is what Linux uses first, when it is shutting down.
- SIGTERM 相当于在窗口中“单击‘X’”。
- SIGTERM 是 Linux 在关闭时首先使用的。
回答by Ohad Schneider
With all the discussion going on here, no code has been offered. Here's my take:
所有的讨论都在这里进行,没有提供代码。这是我的看法:
#!/bin/bash
$pid = 1234
echo "Killing process $pid..."
kill $pid
waitAttempts=30
for i in $(seq 1 $waitAttempts)
do
echo "Checking if process is alive (attempt #$i / $waitAttempts)..."
sleep 1
if ps -p $pid > /dev/null
then
echo "Process $pid is still running"
else
echo "Process $pid has shut down successfully"
break
fi
done
if ps -p $pid > /dev/null
then
echo "Could not shut down process $pid gracefully - killing it forcibly..."
kill -SIGKILL $pid
fi
回答by innaM
HUP sounds like rubbish to me. I'd send it to get a daemon to re-read its configuration.
HUP 对我来说听起来很垃圾。我会把它发送给一个守护进程来重新读取它的配置。
SIGTERM can be intercepted; your daemons just might have clean-up code to run when it receives that signal. You cannot do that for SIGKILL. Thus with SIGKILL you are not giving the daemon's author any options.
SIGTERM 可以被拦截;您的守护进程可能会在收到该信号时运行清理代码。对于 SIGKILL,您不能这样做。因此,使用 SIGKILL 您不会给守护进程的作者任何选择。
More on that on Wikipedia
更多关于维基百科的内容