我有一个脚本,让我们称之为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之外还有什么能帮助我解决这个问题吗?
最简单的事情可能就是每天运行一次,并在两次调用之间休眠的包装脚本
crontab中:
0 0 * * * /home/admin/run-all-jobs.sh arg1 arg2 arg3
run-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
这很容易,而且对于简单的情况就可以很好地工作,但不是很健壮。 克朗为你处理了很多边缘案例。
另一个选择是动态生成crontab,所以你不必手动编辑它。 这个例子以15分钟的时间间隔安排每个作业,所以一旦你有96个以上的作业,它就会开始重叠作业,但是你可以调整它,以不同的时间间隔安排作业。
generate-jobs.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.d
,这个cron
将像你的常规crontab一样读取。
第三个选项,这是多一点涉及,但可能是你真正想要的,是在使用。 at
是一个很棒的工具,可以让你在“将来”某个时间点安排任务。 随着你可以完全避免cron,只要你想安排你的工作。
另一种方法( dimo414答案的变体,最后一个选项使用at
)将运行一个批处理命令。 所以你将有一个单一的 crontab
条目,它将使用batch(1) ( at
一个变体)来运行所有的一百个东西。 甚至在每个命令的循环中调用batch
。
请注意, batch
子系统正在限制您的计算机上的负载(并且可以配置为具有一个批处理作业队列)。 但是,它不会在排队的批处理作业之间休眠。
您可以编写一个包装脚本,将其安排为每小时运行一次,这将根据小时运行具有适当参数的主脚本。
* 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
。 也很容易管理,例如在机器重新启动的情况下,很容易知道将要运行什么,因为它仅取决于当前的时间。