我需要每隔X秒运行一次应用程序,因此,就cron不能以秒的方式工作,我写了一个带有无限循环的bash脚本,其中有X秒睡眠。
当我必须手动停止正在运行的脚本时,我想以正确的方式执行它 - 让应用程序完成正常运行,并且不要再次进入循环。
您有什么想法,如何实现这一目标? 我考虑过传递参数,但是我找不到如何将参数传递给运行脚本。
答案 0 :(得分:24)
你可以捕获一个信号,比如SIGUSR1:
echo "My pid is: $$"
finish=0
trap 'finish=1' SIGUSR1
while (( finish != 1 ))
do
stuff
sleep 42
done
然后,当你想在下一次迭代时退出循环:
kill -SIGUSR1 pid
其中pid
是脚本的进程ID。如果在睡眠期间信号升高,它将被唤醒(睡眠休眠直到出现任何信号)。
答案 1 :(得分:2)
您可以通过文件传递一些参数。在每次迭代中,您可以阅读此文件,看看您的运行条件是否已更改。
答案 2 :(得分:1)
如果你不得不进行一些清理,以下结构可能是合适的。使用kill,如cdarke的回答所示。
#===============================================================
# FUNCTION DEFINITIONS
#===============================================================
# . . .
#=== FUNCTION ================================================
# NAME: cleanup
# DESCRIPTION:
#===============================================================
cleanup ()
{
# wait for active children, remove empty logfile, ..., exit
exit 0
} # ---------- end of function cleanup ----------
#===============================================================
# TRAPS
#===============================================================
trap cleanup SIGUSR1
#===============================================================
# MAIN SCRIPT
#===============================================================
echo -e "Script '$0' / PID ${$}"
while : ; do # infinite loop
# . . .
sleep 10
done
# . . .
#===============================================================
# STATISTICS / CLEANUP
#===============================================================
cleanup
答案 3 :(得分:0)
之前发布的陷阱解决方案适用于大型循环,但对于只是循环一个或几个命令的常见情况很麻烦。在这种情况下,我建议采用以下解决方案:
while whatever; do
command || break
done
如果命令具有非零退出代码,这将退出循环,如果它被中断则会发生。因此,除非command
处理SIGINT
,否则按ctrl-C将停止当前命令并退出循环。
编辑:在更仔细地阅读您的问题之后,我看到您希望当前命令继续执行。在这种情况下,此解决方案不适用。