如何设置 cron 在特定时间只运行一次文件? [关闭]
Posted
技术标签:
【中文标题】如何设置 cron 在特定时间只运行一次文件? [关闭]【英文标题】:How do I set up cron to run a file just once at a specific time? [closed] 【发布时间】:2011-07-25 07:58:06 【问题描述】:如何设置cron
在特定时间只运行一次文件?替代方案之一是at
,但并非所有使用标准托管计划的用户都可以访问它。因此我想知道是否有办法使用cron
来做到这一点?
【问题讨论】:
我尝试在标准 LAMP 服务器上运行$at = shell_exec('at');
,它返回 NULL。因此我认为默认情况下它不起作用(具有权限)。
【参考方案1】:
你真的想使用at
。它正是为此目的而制作的。
echo /usr/bin/the_command options | at now + 1 day
但是,如果您没有 at
,或者您的托管公司不提供对其的访问权限,您可以让 cron 作业包含确保它只运行一次的代码。
设置一个具有非常具体时间的 cron 条目:
0 0 2 12 * /home/adm/bin/the_command options
下一个 /home/adm/bin/the_command 需要确保它只运行一次。
#! /bin/bash
COMMAND=/home/adm/bin/the_command
DONEYET="$COMMAND.alreadyrun"
export PATH=/usr/bin:$PATH
if [[ -f $DONEYET ]]; then
exit 1
fi
touch "$DONEYET"
# Put the command you want to run exactly once here:
echo 'You will only get this once!' | mail -s 'Greetings!' me@example.com
【讨论】:
+ 表示“你真的想使用 at。它正是为此目的而制作的。”,因为这是真的……不过我只是发现了它;那么,为什么不使用它自己的 CLI?除非当前的交互可能在 2015 年之后添加,在这种情况下我的问题并不适用.. 您不必将echo
命令转换为“at”。这只是我做的事情,因为最终我会自动化一切。
嗨@Tomontime,我想知道是否可以像这样触发重启(没有cron),因为这需要sudo/root - 比如echo "reboot" | at now + 9 hour
@ValterEkholm 你可以这样做。但是,通过使用shutdown
并指定正确的标志来重新启动并延迟 9 小时,您可能会获得更好的结果。使用shutdown 命令的好处是它具有中止重启的内置功能;人们可能比atq
更熟悉这些标志。缺点是shutdown
在 Linux、*BSD、Solaris 等上有不同的标志。
啊哈,谢谢,现在我明白了 - 不要使用“at”/只是“使用标志关闭”【参考方案2】:
尝试在 2011 年 3 月 30 日午夜执行命令:
0 0 30 3 ? 2011 /command
警告:如 cmets 中所述,year 列在 cron 的标准/默认实现中不受支持。请参考TomOnTime answer below,了解在cron的标准实现中在未来特定时间运行脚本的正确方法。
【讨论】:
所以这会让它只运行一次?好吧,貌似。但是,有什么办法可以将时间戳转换为cron时间格式吗? 您应该使用问号 (?) 省略“星期几”字段。 来自***:en.wikipedia.org/wiki/Cron#Special_Characters ... '?'字符用于省略指定日期和星期几字段的值。由于为两个字段指定值是无效的,“?”有必要省略其中之一('*' 被视为特定值)。 嗯?什么时候“年”被添加为一列。你能解释一下吗? “标准”crontab 中没有年份。但是检查这个问题:***.com/questions/7724316/… - 一些实现确实允许它。【参考方案3】:你真的想使用at
。它正是为此目的而制作的。
echo /usr/bin/the_command options | at now + 1 day
但是,如果您没有 at
,或者您的托管公司不提供对它的访问权限,您可以创建一个自删除 cron 条目。
遗憾的是,这将删除您的所有 cron 条目。不过,如果你只有一个,这很好。
0 0 2 12 * crontab -r ; /home/adm/bin/the_command options
命令crontab -r
删除您的crontab 条目。幸运的是,命令行的其余部分仍然会执行。
警告:这很危险!它删除所有 cron 条目。如果你有很多,这会将它们全部删除,而不仅仅是具有“crontab -r”行的那个!
【讨论】:
版主注意:这不是Tom's other answer here的转贴,这是使用不同技术的替代答案。【参考方案4】:您可以在/etc/cron.d
中放置一个crontab 文件,该文件将运行一个脚本来运行您的命令,然后删除/etc/cron.d
中的crontab 文件。当然,这意味着您的脚本需要以 root 身份运行。
【讨论】:
【参考方案5】:您的评论表明您正在尝试从编程语言中调用它。如果是这种情况,你的程序可以派生一个调用睡眠的子进程然后工作吗?
让您的程序计算距离所需运行时间的秒数,并让它调用shell_exec("sleep $secondsToWait) ; myCommandToRun");
【讨论】:
你是对的:我正在尝试从 php 运行它。如果 secondsToWait 是 [..] 60*60*24*30,也就是 30 天怎么办?它最终不会杀死服务器吗? (而且我需要开始一份以上的工作;数百份[但它们必须在不同的时间运行]) 您在问题中没有提到一个月后的时间。当然,这会改变一些事情。【参考方案6】:at
是正确的方法。
如果您的机器中没有at
命令并且您也没有安装权限,您可以在cron
上放置类似的内容(可能使用crontab
命令):
* * * 5 * /path/to/comand_to_execute; /usr/bin/crontab -l | /usr/bin/grep -iv command_to_execute | /usr/bin/crontab -
它会执行一次您的命令,然后将其从cron
中删除。
【讨论】:
【参考方案7】:对于无法在环境中访问/安装at
的用户,可以使用自定义脚本:
#!/bin/bash
if [ $# -lt 2 ]; then
echo ""
echo "Syntax Error!"
echo "Usage: $0 <shell script> <datetime>"
echo "<datetime> format: %Y%m%d%H%M"
echo "Example: $0 /home/user/scripts/server_backup.sh 202008142350"
echo ""
exit 1
fi
while true; do
t=$(date +%Y%m%d%H%M);
if [ $t -eq $2 ]; then
/bin/bash $1
echo DONE $(date);
break;
fi;
sleep 1;
done
我们将脚本命名为 run1time.sh 示例可能类似于:
nohup bash run1time.sh /path/to/your/script.sh 202008150300 &
【讨论】:
这似乎无法回答问题。 @NVS Abhilash 这是真正可行的解决方法,可以替代 at 命令。标准/默认实现不支持 cron 中的年份列。以上是关于如何设置 cron 在特定时间只运行一次文件? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章