仅当 cron 任务尚未运行时才运行

2024-11-06 08:34:00
admin
原创
182
摘要:问题描述:我正在尝试设置一个 cron 作业作为我创建的守护进程的看门狗。如果守护进程出错并失败,我希望 cron 作业定期重新启动它...我不确定这有多大可能,但我读过几个 cron 教程,找不到任何可以满足我要求的东西...我的守护进程是从 shell 脚本启动的,所以我实际上只是在寻找一种方法来运行 c...

问题描述:

我正在尝试设置一个 cron 作业作为我创建的守护进程的看门狗。如果守护进程出错并失败,我希望 cron 作业定期重新启动它...我不确定这有多大可能,但我读过几个 cron 教程,找不到任何可以满足我要求的东西...

我的守护进程是从 shell 脚本启动的,所以我实际上只是在寻找一种方法来运行 cron 作业,仅当该作业的上一次运行尚未运行时。

我发现这篇文章确实为我尝试使用锁文件执行的操作提供了解决方案,但我不确定是否有更好的方法来做到这一点......


解决方案 1:

使用flock。它是新的。它更好。

现在您不必自己编写代码。在此处查看更多原因: https: //serverfault.com/a/82863

/usr/bin/flock -n /tmp/my.lockfile /usr/local/bin/my_script

解决方案 2:

我为自己编写的打印后台处理程序执行了此操作,它只是一个 shell 脚本:

#!/bin/sh
if ps -ef | grep -v grep | grep doctype.php ; then
        exit 0
else
        /home/user/bin/doctype.php >> /home/user/bin/spooler.log &
        #mailing program
        /home/user/bin/simplemail.php "Print spooler was not running...  Restarted." 
        exit 0
fi

它每两分钟运行一次,非常有效。如果由于某种原因进程没有运行,我会让它通过电子邮件向我发送特殊信息。

解决方案 3:

正如其他人所说,编写和检查 PID 文件是一个很好的解决方案。这是我的 bash 实现:

#!/bin/bash

mkdir -p "$HOME/tmp"
PIDFILE="$HOME/tmp/myprogram.pid"

if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -opid= |
                           grep -P "^s*$(cat ${PIDFILE})$" &> /dev/null); then
  echo "Already running."
  exit 99
fi

/path/to/myprogram > $HOME/tmp/myprogram.log &

echo $! > "${PIDFILE}"
chmod 644 "${PIDFILE}"

解决方案 4:

令人惊讶的是没有人提到run-one。我已经用这个解决了我的问题。

 apt-get install run-one

run-one然后在 crontab 脚本前添加

*/20 * * * * * run-one python /script/to/run/awesome.py

查看这个askubuntu SE 答案。您也可以在那里找到详细信息的链接。

解决方案 5:

不要尝试通过 cron 来执行此操作。无论如何,让 cron 运行一个脚本,然后让脚本决定程序是否正在运行,并在必要时启动它(请注意,您可以使用 Ruby 或 Python 或您最喜欢的脚本语言来执行此操作)

解决方案 6:

我在运行 php 脚本时执行的方式是:

crontab:

* * * * * php /path/to/php/script.php &

PHP代码:

<?php
if (shell_exec('ps aux | grep ' . __FILE__ . ' | wc  -l') > 1) {
    exit('already running...');
}
// do stuff

此命令在系统进程列表中搜索当前 php 文件名,如果存在,则行计数器(wc -l)将大于一,因为搜索命令本身包含文件名

因此如果您运行 php cron,请将上述代码添加到 php 代码的开头,它将只运行一次。

解决方案 7:

您也可以直接在 crontab 中将其作为一行程序执行:

* * * * * [ `ps -ef|grep -v grep|grep <command>` -eq 0 ] && <command>

解决方案 8:

作为对 Earlz 回答的后续,您需要一个包装器脚本,该脚本在启动时创建一个 $PID.running 文件,并在结束时删除。包装器脚本调用您想要运行的脚本。包装器是必需的,以防目标脚本失败或出错,pid 文件会被删除。

解决方案 9:

lockrun不需要为您的 cron 作业编写包装脚本。http ://www.unixwiz.net/tools/lockrun.html

解决方案 10:

# one instance only (works unless your cmd has 'grep' in it)
ALREADY_RUNNING_EXIT_STATUS=0
bn=`basename $0`
proc=`ps -ef | grep -v grep | grep "$bn" | grep -v " $$ "`
[ $? -eq 0 ] && {
    pid=`echo $proc | awk '{print $2}'`
    echo "$bn already running with pid $pid"
    exit $ALREADY_RUNNING_EXIT_STATUS
}

更新..使用flock的更好方法:

/usr/bin/flock -n /tmp/your-app.lock /path/your-app args 

解决方案 11:

我建议使用现有的工具,例如monit ,它将监视并自动重启进程。这里有更多信息。它应该在大多数发行版中都很容易获得。

解决方案 12:

这个从来没有让我失望过:

one.sh

LFILE=/tmp/one-`echo "$@" | md5sum | cut -d  -f1`.pid
if [ -e ${LFILE} ] && kill -0 `cat ${LFILE}`; then
   exit
fi

trap "rm -f ${LFILE}; exit" INT TERM EXIT
echo $$ > ${LFILE}

$@

rm -f ${LFILE}

计划任务

* * * * * /path/to/one.sh <command>

解决方案 13:

文档:https://github.com/timkay/solo

solo 是一个非常简单的脚本(10 行),可防止程序一次运行多个副本。它与 cron 一起使用可确保在前一个作业完成之前不会运行下一个作业。

例子

* * * * * solo -port=3801 ./job.pl blah blah

解决方案 14:

我建议对rsanden 的回答进行以下改进(我会以评论的形式发布,但声誉不够……):

#!/usr/bin/env bash

PIDFILE="$HOME/tmp/myprogram.pid"

if [ -e "${PIDFILE}" ] && (ps -p $(cat ${PIDFILE}) > /dev/null); then
  echo "Already running."
  exit 99
fi

/path/to/myprogram

这避免了可能的错误匹配(以及 grepping 的开销),并且它抑制输出并仅依赖于 ps 的退出状态。

解决方案 15:

简单的自定义 php 就足以实现。无需与 shell 脚本混淆。

假设你想运行php /home/mypath/example.php如果没有运行

然后使用以下自定义 php 脚本来完成相同的工作。

创建以下/home/mypath/forever.php

<?php
    $cmd = $argv[1];
    $grep = "ps -ef | grep '".$cmd."'";
    exec($grep,$out);
    if(count($out)<5){
        $cmd .= ' > /dev/null 2>/dev/null &';
        exec($cmd,$out);
        print_r($out);
    }
?>

然后在你的 cron 中添加以下内容

* * * * * php /home/mypath/forever.php 'php /home/mypath/example.php'

解决方案 16:

如果你要走这条路,请考虑使用 pgrep(如果可用)而不是通过 grep 管道传输的 ps。不过,就我个人而言,我从以下形式的脚本中获得了很大的收益

while(1){
  call script_that_must_run
  sleep 5
}

虽然这可能会失败,但 cron 任务通常处理重要事务的最佳方式。这只是另一种选择。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用