例如,我有一个带有无限循环的脚本将某些内容打印到stdout。我需要捕获一个信号(例如SIGHUP),因此它将使用不同的PID重新启动脚本,循环将从0再次启动。杀戮和启动不能按预期工作:
function traphup(){
kill $0
exec $0
}
trap traphup HUP
也许我应该在后台放置一些东西或使用nohup,但我不熟悉这个命令。
答案 0 :(得分:3)
在你的功能中:
traphup(){
$0 "$@" &
exit 0
}
这将在后台启动一个新进程,其中包含原始命令名称和参数(根据您的要求更改参数)以及新进程ID。原来的shell然后退出。如果您的守护程序使用一个标识符来识别自己,请不要忘记整理PID文件 - 但重启可能会这样做。
请注意,使用nohup
将是错误的方向;第一次启动守护进程时,它会响应HUP信号,但是使用nohup
启动的信号将忽略该信号,而不是重新启动 - 除非您明确覆盖'ignore'状态,这是一个坏主意出于各种原因。
我不太确定是什么问题。
当我运行以下脚本时,我只会在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>
”的是原始流程;第二组是子进程(1649)报告其父进程(1155)。此输出可以轻松跟踪将HUP信号发送到哪个进程。 (初始echo和sleep使得命令行提示不受输出限制。)
我怀疑你所看到的内容取决于你脚本的内容 - 在我的例子中,循环的主体很简单。但是,如果我有一个管道或其他东西,那么我可能会看到第二个具有相同名称的进程。但我认为这不会改变,具体取决于原始脚本是在前台还是后台运行。