我可以比每分钟更频繁地运行 cron 作业吗?

use*_*336 54 linux cron

是否可以在没有 sleep 命令的情况下每 30 秒运行一次 cron 作业?

Den*_*son 50

最有创意地 滥用Linux 命令的候选者:

nohup watch -n 30 --precise yourprog >/dev/null &
Run Code Online (Sandbox Code Playgroud)

如果yourprog包括:

date +%M.%S.%N >> yourprog.out
Run Code Online (Sandbox Code Playgroud)

那么yourprog.out可能看起来像:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676
Run Code Online (Sandbox Code Playgroud)

表示相当不错的精度水平。

下面是对命令部分的解释:

  • nohup-watch在这种情况下,这可以防止跟随它的命令在终端退出时退出。
  • watch- 该程序重复运行一个命令。通常,每次watch运行该命令时,都会显示该命令的第一屏输出。
  • -n 30- 运行命令的时间间隔。在这种情况下,它是每三十秒一次。
  • --precise- 如果没有此选项,watch 间隔运行命令。有了它,该命令的每次启动开始 的间隔,如果可能的。如果示例中未指定此选项,则由于启动和执行命令 ( yourprog)所需的时间,时间会越来越晚,每次都会超过 30 秒。
  • yourprog-watch要执行的程序或命令行。如果命令行包含 shell 特有的字符(例如空格或分号),则需要将其引用。
  • >/dev/null- 大于号将正在运行的命令的输出重定向watch到文件 /dev/null. 该文件会丢弃写入其中的任何数据。这可以防止将输出写入屏幕,或者,由于nohup正在使用,它可以防止将输出发送到名为nohup.out.
  • &-watch命令在后台运行,控制权返回给终端或父进程。

请注意,nohup输出重定向和&后台控制运算符并非特定于watch.

以下是示例yourprog脚本的说明:

  • date- 输出当前日期和/或时间。它也可以设置它们。
  • +%M.%S.%N- 这指定date要使用的输出格式。%M是当前分钟,%S是当前秒,%N是当前纳秒。
  • >> yourprog.out- 这会将date命令的输出重定向到名为yourprog.out. 双大于号会导致每次调用时将输出附加到文件中,而不是覆盖之前的内容。

编辑

可能被滥用的另一件事(或者它可能是合法使用)是 systemd 计时器。

请参阅systemd/Timers 作为 cron 替代品Cron vs systemd timers

我会尽快发布一个例子。

  • 我给纯脸颊+1 (8认同)
  • 对这个答案有更多的解释会很好。nohup 命令对我来说是新的。互联网告诉我这是忽略挂断信号。这仍然让我感到困惑。 (2认同)
  • @donquixote:重要的是要认识到我的答案中的整个命令不是推荐的做法,因此使用了“误用”一词。但是,为了让您稍微澄清一些事情,因为其中包含有用的技术,我将尝试描述一些。`&` 使命令在后台运行,立即将控制权返回到命令提示符。使用 `nohup` 命令会导致后台进程(在本例中为 `watch`)忽略在 shell 退出时发送的挂断信号,例如当你关闭终端时。... (2认同)

小智 38

如果您的任务需要频繁运行,那么 cron 是错误的工具。除了它不会那么频繁地启动作业这一事实之外,如果作业运行时间超过启动间隔时间,您还会面临一些严重问题的风险。重写您的任务以进行守护进程并持久运行,然后在必要时从 cron 启动它(同时确保如果它已经在运行则不会重新启动)。

  • “如果作业运行时间超过启动间隔时间,您也会面临一些严重问题的风险。” 不是真的,如果是这样,它同样适用于每 5 分钟、每小时或每月运行一次的作业。该问题有解决方案(使用 pidfile 或其他方法并在运行之前检查作业是否已在运行)。所以问题是 cron 不会允许这个频率,但是说每隔不到一分钟执行一次任务就存在本质上的错误是不正确的。 (23认同)
  • 正如下面的答案所显示的那样,这是很有可能的,尽管有点老套。为什么你做错了!!!!这里接受的答案,当它根本不回答问题时? (6认同)
  • 您可以使用 `run-one` 来确保程序/甚至 PHP 脚本不会启动重复的实例。`sudo apt-get install run-one` 并通过 `run-one <normal command>` 调用它 (3认同)
  • 我的意思是如果你不使用pidfile。如果您的作业每 X 分钟运行一次,并且需要超过 X 分钟才能完成,那么您最终会堆积作业。如果您的工作还受到某种资源(CPU、网络/磁盘带宽等)的限制,那么一次运行更多将使完成工作所需的时间更长,最终您的计算机将变成一团糟。 (2认同)

Bal*_*sár 17

Cron 被设计成每分钟醒来一次,所以如果没有一些黑客攻击,例如像你提到的那样睡觉,就不可能做到这一点。


gho*_*oti 16

* * * * * /path/to/program
* * * * * sleep 30; /path/to/program
Run Code Online (Sandbox Code Playgroud)

不要忘记在您的程序中写入一些内容,以便在前一个实例已经在运行时退出。

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi
Run Code Online (Sandbox Code Playgroud)

当然,这仍然留下非常小的失败机会,因此请在 google 中搜索适用于您的环境的更好的解决方案。

  • 发现此问题的其他访问者并不关心是否使用了 sleep 命令:) (14认同)

0x6*_*16E 11

您可以使用第三方软件执行此操作。

对我来说效果很好的一个选项是frequent-cron

它允许毫秒精度,并为您提供推迟下一次执行的选项,直到当前执行退出。