如何使用信号从自身重新启动 BASH 脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4663273/
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-17 23:14:53  来源:igfitidea点击:

How to restart a BASH script from itself with a signal?

bashunixsignals

提问by Oink

For example I have script with an infinite loop printing something to stdout. I need to trap a signal (for example SIGHUP) so it will restart the script with different PID and the loop will start itself again from 0. Killing and starting doesn't work as expected:

例如,我有一个无限循环的脚本,将某些内容打印到标准输出。我需要捕获一个信号(例如 SIGHUP),因此它将使用不同的 PID 重新启动脚本,并且循环将从 0 重新开始。杀死和启动无法按预期工作:

function traphup(){  
    kill 
traphup(){
    
#!/bin/bash

traphup()
{
    
<none>: 1155: 21
<none>: 1155: 22
<none>: 1155: 23

1155: 1649: 1
1155: 1649: 2
1155: 1649: 3
1155: 1649: 4
"$$" & exit 0 } trap traphup HUP echo sleep 1 i=1 while [ $i -lt 1000 ] do echo "${1:-<none>}: $$: $i" sleep 1 : $(( i++ )) done
"$@" & exit 0 }
exec ##代码## } trap traphup HUP

Maybe I should place something in background or use nohup, but I am not familiar with this command.

也许我应该在后台放置一些东西或使用 nohup,但我不熟悉这个命令。

回答by Jonathan Leffler

In your function:

在您的功能中:

##代码##

This starts a new process in the background with the original command name and arguments (vary arguments to suit your requirements) with a new process ID. The original shell then exits. Don't forget to sort out the PID file if your daemon uses one to identify itself - but the restart may do that anyway.

这会在后台使用原始命令名称和参数(根据您的要求改变参数)和新进程 ID 启动一个新进程。然后原始外壳退出。如果您的守护进程使用 PID 文件来标识自己,请不要忘记整理 PID 文件 - 但无论如何重启可能会这样做。

Note that using nohupwould be the wrong direction; the first time you launched the daemon, it would respond to the HUP signal, but the one launched with nohupwould ignore the signal, not restarting again - unless you explicitly overrode the 'ignore' status, which is a bad idea for various reasons.

请注意,使用nohup将是错误的方向;第一次启动守护进程时,它会响应 HUP 信号,但启动的进程nohup会忽略该信号,不会再次重新启动 - 除非您明确覆盖“忽略”状态,由于各种原因,这是一个坏主意。



Answering comment

回复评论

I'm not quite sure what the trouble is.

我不太确定问题是什么。

When I run the following script, I only see one copy of the script in psoutput, regardless of whether I start it as ./xx.shor as ./xx.sh &.

当我运行以下脚本时,ps无论我是./xx.sh作为./xx.sh &.

##代码##

The output contains lines such as:

输出包含以下行:

##代码##

The ones with '<none>' are the original process; the second set are the child process (1649) reporting its parent (1155). This output made it easy to track which process to send HUP signals to. (The initial echo and sleep gets the command line prompt out of the way of the output.)

带' <none>'的是原始进程;第二组是报告其父进程 (1155) 的子进程 (1649)。此输出使跟踪将 HUP 信号发送到哪个进程变得容易。(初始的 echo 和 sleep 将命令行提示符排除在输出之外。)

My suspicion is that what you are seeing depends on the content of your script - in my case, the body of the loop is simple. But if I had a pipeline or something in there, then I might see a second process with the same name. But I don't think that would change depending on whether the original script is run in foreground or background.

我怀疑您所看到的内容取决于脚本的内容 - 就我而言,循环的主体很简单。但是如果我有一个管道或其他东西,那么我可能会看到同名的第二个进程。但我不认为这会根据原始脚本是在前台还是后台运行而改变。