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

标签 bash unix signals

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

function traphup(){  
    kill $0  
    exec $0
}  
trap traphup HUP

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

最佳答案

在您的功能中:

traphup(){
    $0 "$@" &
    exit 0
}

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

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

回复评论

我不太确定问题是什么。

当我运行以下脚本时,我只能在 ps 中看到该脚本的一个副本输出,无论我是否以 ./xx.sh 开头或作为 ./xx.sh & .
#!/bin/bash

traphup()
{
    $0 "$$" &
    exit 0
}

trap traphup HUP
echo
sleep 1

i=1
while [ $i -lt 1000 ]
do
    echo "${1:-<none>}: $$: $i"
    sleep 1
    : $(( i++ ))
done

输出包含以下行:
<none>: 1155: 21
<none>: 1155: 22
<none>: 1155: 23

1155: 1649: 1
1155: 1649: 2
1155: 1649: 3
1155: 1649: 4

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

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

关于bash - 如何使用信号从自身重新启动 BASH 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4663273/

相关文章:

bash - 如果命令在变量中,则在子 shell 中执行管道命令不起作用

linux - Bash 脚本 - if block 中的 boolean 值?

c - SIGIO从不开火

objective-c - 您对通知和委托(delegate)的替代方案的看法 : Signals?

linux - Cronjob 运行时返回错误

ruby - 在 linux 上的 ruby​​ 中,有没有办法获取捕获信号的 siginfo_t 数据?

linux - xterm 不运行 shell 脚本

c - 带系统函数的 C 程序中的大括号扩展

linux - 一起计算 n 行的平均值

bash - 计算 UTF-8 文件中的字符