在 shell 脚本中,我执行以下操作:
#!/bin/sh
while true; do <some application>; sleep 1; done &
... rest of the scrip ...
这保证了应用程序始终运行,因为这是脚本的其余部分所需要的。不过,该脚本具有弹性,因此如果应用程序似乎未运行且响应不正确,它将稍后重试。
当主脚本终止时,例如由于 aSIGTERM
或SIGINT
,我希望该while
循环也停止。主脚本终止后无需保持应用程序运行。
在 shell 脚本中执行此操作的常用方法是什么?请注意,我想要两件事:
- 防止重新执行应用程序
- 尽快停止当前正在进行的应用程序实例
我不知道如何在 shell 脚本中完成这一切。我可以捕获INT
和TERM
,但我不确定如何将逻辑注入循环while
以及如何停止应用程序。
请注意,我目前正在 plain 中工作,但如果需要,sh
我可以继续使用。bash
答案1
您在脚本中想要的不是无限循环,而是锁定文件。
然后调用在包装器脚本中执行工作的脚本。
#!/bin/sh
if [ -f /tmp/.lock.my-mgr ]
then
echo "Program in use ... exiting ..."
exit 10
fi
/bin/touch /tmp/.lock.my-mgr
/usr/local/bin/myscript.sh
/bin/rm /tmp/.lock.my-mgr
如果您希望每隔几分钟批量执行此任务,请使用 cron 来安排该任务。
编辑:
与循环一起运行的脚本的 PID 可以放入一个文件中,内容如下
echo $! > /var/tmp/script1.pid
(在一个脚本中)。
要测试它是否是从第二个脚本启动的,请使用 ps 命令,例如
ps -p `cat /var/tmp/script1.pid`
然后用 $? 测试它的状态如果 ps 找到该 pid,则该变量应为 0;如果没有,则应为 1。这是基本逻辑,但可以通过更好的测试来编写它,例如 pid 文件不存在的情况。
答案2
while true; do <some application>; sleep 1; done &
myloop=$! # get the pid of the child
# kill $myloop
# where/when you think you need to stop the child process
&
在后台创建一个子进程。还有其他命令可以处理类似的工作fg
,您可能需要考虑。