【问题标题】:Running many small scripts throughout the day with cron使用 cron 全天运行许多小脚本
【发布时间】:2023-03-06 17:14:01
【问题描述】:

我有一个脚本,我们将它命名为我想运行的 run-jobs.sh。它接受 1 个参数。我目前设置的是一个 cron

1 7 * * * /home/admin/run-jobs.sh arg1
2 7 * * * /home/admin/run-jobs.sh arg2
3 7 * * * /home/admin/run-jobs.sh arg3

我有许多不同的参数(比如说 100 个)要运行,但我想将它分散到一整天,这样它就不会一次运行所有的参数。使用 cron 执行此操作的最佳方法是什么,而不必制作庞大的 cron 列表并且每次都必须对其进行编辑?除了 cron 之外,还有什么可以帮助我解决这个问题的吗?

【问题讨论】:

    标签: linux bash cron


    【解决方案1】:

    最简单的事情可能是只拥有一个每天运行一次并在调用之间休眠的包装脚本,例如

    crontab:

    0 0 * * * /home/admin/run-all-jobs.sh arg1 arg2 arg3
    

    运行-all-jobs.sh:

    for arg in "$@"; do
      # run the job as a background task,
      # so the job's duration doesn't throw off the timing
      run-jobs.sh "$arg" &
      # split the args evenly around 24 hours
      sleep $(( 24 * 60 * 60 / $# ))
    done
    

    这很容易,对于简单的情况也可以正常工作,但它不是很健壮。 Cron 为你处理了很多边缘情况。


    另一个选项是动态生成 crontab,因此您不必手动编辑它。此示例以 15 分钟的间隔安排每个作业,因此一旦您的作业超过 96 个,它将开始重叠作业,但您可以对其进行调整以以不同的间隔安排作业。

    生成作业.sh:

    for (( i=1; i<=$#; i++ )); do
      printf "%d %d * * * /home/admin/run-jobs.sh '%s'\n" \
          "$(( i / 4 ))" "$(( i % 4 ))" "${!i}"
    done > /etc/cron.d/run-jobs.cron
    

    这会将文件写入/etc/cron.dcron 将像您的常规 crontab 一样读取该文件。


    第三个选项是使用at,它涉及更多一点,但可能是您真正想要的。 at 是一个很棒的工具,可让您在未来的某个时间点安排任务。使用at,您可以完全避免使用 cron,并且可以随时安排您的工作。

    【讨论】:

    • 谢谢!这正是我一直在寻找的,但不知道它叫什么。我会检查'at'。我也会看看其他 2 个解决方案是否对我有用。
    • 我使用了方法 1,因为它非常简单且易于设置。唯一不同的是,我没有写出 cron 中的所有参数(我不知道行长的限制是什么),而是用我的所有参数和 run-all-jobs.sh 循环制作了一个简单的 txt 文件通过文件。这样,当我需要输入新参数时,编辑 txt 文件非常简单。
    【解决方案2】:

    另一种方式(dimo414 answer 的变体,使用at 的最后一个选项)是运行单个批处理命令。所以你会有一个 single crontab 条目,它将使用 batch(1)at 的变体)来运行所有一百个东西。甚至在每个命令的循环中调用batch

    请注意,batch 子系统限制了您机器上的负载(并且可以配置为具有单个批处理作业队列)。但是,它不会在排队的批处理作业之间休眠。

    【讨论】:

      【解决方案3】:

      你可以写一个包装脚本, 安排它每小时运行一次, 这将根据小时使用适当的参数运行主脚本。

      * 7 * * * /home/admin/run-jobs-wrapper.sh
      

      包装器可能是这样的:

      case "$(date +%H)" in
      01) /home/admin/run-jobs.sh arg1 ;;
      02) /home/admin/run-jobs.sh arg2 ;;
      ...
      esac
      

      (请注意,date +%H 会输出以 0 填充的小时。)

      这样你就会有一些容易理解的东西, 易于控制在可以置于版本控制下的单个脚本中, 无需创建大的crontab。 也很容易管理, 例如在机器重启的情况下, 很容易知道究竟会运行什么, 因为它只取决于当前时间。

      【讨论】:

        猜你喜欢
        • 2011-05-26
        • 2011-05-28
        • 2023-04-09
        • 1970-01-01
        • 2022-06-16
        • 2011-09-29
        • 2015-03-16
        • 2012-06-03
        相关资源
        最近更新 更多