& 符号是你的朋友

& 符号是你的朋友

有没有办法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>&1stderr将(2) 与stdout(1)连接,nohup然后隐式将输出发送到nohup.out

如果您不添加 & 符号 - 那么调用者(此处为 php)将等待作业完成。

如果你像卡斯一样掉进兔子洞指出- 然后你可以看到人们如何使用这种技术与shell_execexec(参见这里

从中了解的其他重要信息:

如果您对任何输出不感兴趣,可以将其发送到/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

但是-再次-请-不要:-)

如果一切都失败了……

如果全部失败,请重述您的问题。运行调度工具现在不是你问题的根本原因。如果以上还不够 - 那么我们需要更深入地挖掘。

相关内容