如果 cronjob 正在运行,如何暂停/恢复?

如果 cronjob 正在运行,如何暂停/恢复?

我已尝试此解决方案来防止重复的 cronjob 运行。

30,31 12 * * * /usr/bin/flock -n /tmp/my.lockfile ~/Desktop/test.sh >> ~/Desktop/test.log 2>&1

并且脚本test.sh

#!/bin/bash

for i in {1..40};do
    echo "hello$i"
    sleep 2
done

脚本test.sh已成功阻止在 12:31 运行,但它已停止,我想恢复它。我怎样才能让它只暂停,不停止并恢复?可能吗?

答案1

您可以添加测试在脚本的开头,检查是否有其他早期启动的脚本实例,如果是,则当前实例将进入休眠状态。如下所示:

while ps aux | grep -v 'grep' | grep "$0" | sed -e "/$$/p" -e "/$$/,$ d" | grep -vq "$$"
do sleep 1
done

在哪里:

  • 变量$0包含脚本名称(和执行路径);

  • 该变量$$包含脚本当前运行实例的 PID;

  • ps aux- 输出当前流程;

  • grep -v 'grep'grep- 保留前一个命令输出中包含的行;

  • grep "$0"- 仅输出与当前脚本名称相关的行;

  • sed -e "/$$/p" -e "/$$/,$ d"- 删除脚本的较新实例;删除包含当前实例 PID 的行之后的所有行;

  • grep -vq "$$"- 这是实际的测试-q,当删除当前实例的 PID 行时,将返回0(true - 至少有一个较旧的脚本实例)或1(false - 显然这是最新的现有脚本实例)-v

这是一个完整的例子:

#!/bin/bash

while ps aux | grep -v 'grep' | grep "$0" | sed -e "/$$/p" -e "/$$/,$ d" | grep -vq "$$"
do
        sleep 1
        echo -n '.'
done

date +"%T"

for i in {1..5};do
    echo "hello$i"
    sleep 2
done

以下是我所做的测试:

在此处输入图片描述

此外,您还可以创建一个启动器脚本,它将以上述方式执行您的实际脚本。

$ cat ~/Desktop/test-cron-launcher.sh 
#!/bin/bash

LAUNCH_TIME="$(date +"%T")"

while ps aux | grep -v 'grep' | grep "$0" | sed -e "/$$/p" -e "/$$/,$ d" | grep -vq "$$"
do sleep 1
done

echo "Job from $LAUNCH_TIME begin at $(date +"%T")"

. "$HOME/Desktop/test.sh"
$ cat ~/Desktop/test.sh 
#!/bin/bash
for i in {1..40};do
    echo "hello$i"
    sleep 2
done
$ crontab -l | grep 'test'
30,31 12 * * * "$HOME/Desktop/test-cron-launcher.sh" >> "$HOME/Desktop/test.log" 2>&1

另请阅读:

相关内容