例如,我有一个无限循环的脚本,将某些内容打印到标准输出。我需要捕获一个信号(例如 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/