8

我需要每隔 X 秒运行一次应用程序,因此,只要 cron 不能以这种方式使用秒数,我就编写了一个带有无限循环的 bash 脚本,其中有 X 秒睡眠。

当我必须手动停止正在运行的脚本时,我想以正确的方式进行 - 让应用程序完成运行,并且下次不要进入循环。

你有什么想法,如何实现?我考虑过传递参数,但我找不到如何将参数传递给正在运行的脚本。

4

4 回答 4

26

你可以捕获一个信号,比如 SIGUSR1:

echo "My pid is: $$"
finish=0
trap 'finish=1' SIGUSR1

while (( finish != 1 ))
do
    stuff
    sleep 42
done

然后,当您想在下一次迭代中退出循环时:

kill -SIGUSR1 pid

pid脚本的进程 ID在哪里。如果在睡眠期间发出信号,它将唤醒(睡眠一直到任何信号出现)。

于 2012-06-26T08:32:20.393 回答
2

您可以通过文件传递一些参数。在每次迭代中,您都可以阅读此文件并查看您的运行条件是否已更改。

于 2012-06-26T08:16:55.253 回答
1

前面发布的陷阱解决方案适用于大型循环,但对于仅循环单个或几个命令的常见情况来说很麻烦。在这种情况下,我推荐以下解决方案:

while whatever; do
    command || break
done

如果命令有一个非零退出代码,这将退出循环,如果它被中断就会发生。因此,除非commandhandle SIGINT,否则按 ctrl-C 将停止当前命令并退出循环。

编辑:更仔细地阅读您的问题后,我看到您希望当前命令继续执行。在这种情况下,此解决方案不适用。

于 2013-02-06T10:45:29.693 回答
1

如果您无论如何都必须进行一些清理,则以下结构可能是合适的。如 cdarke 的答案所示使用 kill 。

#===============================================================
#  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
于 2012-06-26T12:29:42.230 回答