有没有办法at
立即在FreeBSD上运行?
在 Ubuntu 上,当我使用“at now”运行脚本时,它会立即运行。对于 FreeBSD,存在延迟,因为 at 是通过 crontab 运行的。默认值为 5m。
*/5 * * * * root /usr/libexec/atrun
我把它改为每1m运行一次。
*/1 * * * * root /usr/libexec/atrun
1m还是相当漫长的等待。有没有办法at
像在 Ubuntu 上那样立即在 FreeBSD 上运行?
编辑:这是我用来运行at
命令的代码。at now
在 Ubuntu 上可以立即运行,但不能在 FreeBSD 上运行。我不知道如何弄清楚at
在 Ubuntu 上是如何运行的,但 FreeBSD 它是在 crontab 调度上运行的,导致了延迟。
shell_exec("echo /usr/local/bin/php -q scripts/myfile.php {$var1} {$var2} | at now");
编辑:尝试在手动(而不是等待 cron)后立即运行 atrun 会产生以下错误。
atrun: setegid failed: Operation not permitted
我不确定如何通过授予用户运行其自己的计划命令的权限来解决这个问题。
答案1
& 符号是你的朋友
请不要拿着剪刀奔跑。您出于所有错误的原因提出了一个非常有效的问题。
at
用于cron
安排未来的工作。它们是实现这一目的的绝佳工具。但是,当您现在使用日程安排工具来完成工作时,您就是在涉水填水。梅尔布尔斯兰向您指出了这一点,并为您提供了正确的答案。然后你试图澄清你的需求 - 但不幸的是没有理解他的观点。当您应该简单地使用 & 符号时,您却坚持使用at
- &
。
对于其他读者 - 问题更多的是“如何让 php 运行(生成)另一个脚本并继续而不等待脚本完成?”。
然后,这将引导您了解一些很棒的 UNIX 基础知识,正如 MelBurslan 向您展示的那样:
nohup /path/to/myprogram & 2>&1
nohup
确保即使当前用户注销,该命令仍将在后台运行。&
您可能缺少的是:& 符号断开进程并将其发送到后台。2>&1
stderr
将(2) 与stdout
(1)连接,nohup
然后隐式将输出发送到nohup.out
如果您不添加 & 符号 - 那么调用者(此处为 php)将等待作业完成。
如果你像卡斯一样掉进兔子洞指出- 然后你可以看到人们如何使用这种技术与shell_exec
和exec
(参见这里)
从中了解的其他重要信息:
如果您对任何输出不感兴趣,可以将其发送到/dev/null
如下所示:
> /dev/null
这将重定向stdout
。如果您也不想要任何错误消息,您可以stderr
像这样重定向:
2> /dev/null
您可以将它们组合成一行:
> /dev/null 2> /dev/null
有一个简短的形式 - 将 stderr 发送到 stdout - 并将 stdout 发送到“nothing”:
> /dev/null 2>&1
那么让我们将这些知识付诸实践:
你的例子误用了at
:
shell_exec("echo /usr/local/bin/php -q scripts/myfile.php {$var1} {$var2} | at now");
但如果您只是想让它继续您的脚本 - 只需添加&符号&
shell_exec("/usr/local/bin/php -q scripts/myfile.php {$var1} {$var2} &");
如果您不使用任何输出 - 那么您应该重定向它。
shell_exec("/usr/local/bin/php -q scripts/myfile.php {$var1} {$var2} > /dev/null 2>&1 &");
Brent Braisley 建议的最优雅的版本是:
exec("nohup /usr/bin/php -q scripts/myfile.php {$var1} {$var2} > /dev/null 2>&1 &");
过度使用
该at
命令安排脚本运行的命令atrun
。
如果您阅读了手册页因为at
你会发现:
Note that at is implemented through the cron(8) daemon by calling
atrun(8) every five minutes. This implies that the granularity of at
might not be optimal for every deployment. If a finer granularity is
needed, the system crontab at /etc/crontab needs to be changed.
您已经调整了 crontab。对于你的情况,我建议不要这样做。但如果你坚持你应该看看人 crontab (5):
string meaning
------ -------
@reboot Run once, at startup of cron.
@yearly Run once a year, "0 0 1 1 *".
@annually (same as @yearly)
@monthly Run once a month, "0 0 1 * *".
@weekly Run once a week, "0 0 * * 0".
@daily Run once a day, "0 0 * * *".
@midnight (same as @daily)
@hourly Run once an hour, "0 * * * *".
@every_minute Run once a minute, "*/1 * * * *".
@every_second Run once a second.
这意味着您可以将*/1
(每分钟一次)更改为@every_second
.
但是-请-不要:-)
手动运行 atrun
您不应该atrun
按照您的建议滥用。它所做的“所有”(在您的上下文中)是添加&符号&
以在后台执行您的作业。
失败的最可能原因是您(您应该如此!)以普通用户身份登录。at
默认情况下只有 root 有权使用。如果您需要更改此设置 - 请查看 at 和 的手册页:
/var/at/at.allow allow permission control
/var/at/at.deny deny permission control
但是-再次-请-不要:-)
如果一切都失败了……
如果全部失败,请重述您的问题。运行调度工具现在不是你问题的根本原因。如果以上还不够 - 那么我们需要更深入地挖掘。