如何以编程方式创建新的cron作业?

Dav*_*idM 125 unix linux cron

我希望能够以编程方式添加新的cron作业,这样做的最佳方法是什么?

根据我的研究,似乎我可以转储当前的crontab,然后添加一个新的,将其回送到crontab:

(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

Mar*_*rkR 125

如果以root身份运行,最好的方法是将文件放入/etc/cron.d

如果您使用包管理器打包软件,您可以简单地在该目录中放置文件,它们被解释为它们是crontabs,但是有一个额外的用户名字段,例如:

文件名: /etc/cron.d/per_minute

内容: * * * * * root /bin/sh /home/root/script.sh

  • 对此的一个潜在警告是cron获取此文件夹的新增内容的频率(每小时一次).如果您希望自己的工作立即开始运行,请注意. (10认同)
  • 这是最简单,最优雅的解决方案.当然需要使用其他不相关的条目来解析和编辑现有的crontab. (8认同)
  • @JonathanK,你碰巧知道是否可以要求cron重新扫描`/ etc/cron.d/*`?如果必须等待一个小时来检查,很难知道某些东西是否有效! (5认同)
  • 只需确保使用的cron版本支持/etc/cron.d/.大多数现代Linux发行版都有. (4认同)
  • 如何为这个文件设置烫发?chmod + x /etc/cron.d/per_minute? (4认同)

小智 91

OP的解决方案有一个错误,它可能允许条目添加两次,使用下面的修复.

(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
Run Code Online (Sandbox Code Playgroud)

  • 为了确保唯一性,只需在`uniq`之前"排序",例如:`(crontab -l; echo"0****your_command")| 排序 - | uniq - | crontab -` (6认同)
  • 如果没有描述解决方案,这实际上是更好的.它确保命令不会两次添加到crontab. (5认同)
  • 不需要`uniq`.在`sort`上使用`-u`选项. (5认同)
  • 当我第一次编辑crontab时,如何避免用户**没有crontab. (3认同)
  • 对于重复输入问题,这几乎不是一个好方法.如果在此期间另外一行添加到crontab怎么办? (2认同)
  • 这有一个(小但危险的)竞争条件。 (2认同)
  • @wyx 在此处查看我对“无 crontab”问题的回答:) (2认同)

小智 22

添加一些东西给cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -
Run Code Online (Sandbox Code Playgroud)

从cron中删除它

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh |  sort | uniq | crontab -
Run Code Online (Sandbox Code Playgroud)

希望对某人有所帮助

  • 你实际上不应该需要`2>&1 | grep -v"no crontab"`因为当没有crontab时,输出行`crontab:no crontab for ...`被发送到stderr.没有理由捕获该输出,将其发送到stdout,然后使用grep将其过滤掉.如果您的目标是避免在输出中看到`crontab:no crontab for ...`,那么使用`2>/dev/null | 排序....`. (2认同)

Eld*_*mir 8

这里的大多数解决方案都是为 crontab 添加行。如果您需要更多控制,您将希望能够控制 crontab 的全部内容。

您可以使用管道来非常优雅地完成此操作。

要完全重写 crontab,请执行

echo "2 2 2 2 2 /bin/echo foobar" |crontab -
Run Code Online (Sandbox Code Playgroud)

这应该很容易与此处描述的其他答案相结合,例如

crontab -l | <something> | tee |crontab -
Run Code Online (Sandbox Code Playgroud)

或者,如果你有一个文件中的内容,那就更简单了

cat <file> |crontab -
Run Code Online (Sandbox Code Playgroud)


Chr*_*tts 6

如果你打算为一个只运行的东西做一次运行的场景,那么看看'at'


小智 6

只需将编辑器更改为tee命令:

export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e
Run Code Online (Sandbox Code Playgroud)

  • 当心 - 这会擦除任何现有条目。 (5认同)

Tim*_*ara 5

假设您的crontab中已经有一个条目,那么以下命令应该可以很好地工作。请注意,该$CMD变量仅在此处具有可读性。在过滤重复项之前进行排序很重要,因为它uniq仅适用于相邻的行。

CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -
Run Code Online (Sandbox Code Playgroud)

如果当前crontab为空,则stderr会收到以下错误消息:

no crontab for user
Run Code Online (Sandbox Code Playgroud)

如果要避免这种情况,可以增加一点复杂度,然后执行以下操作:

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -
Run Code Online (Sandbox Code Playgroud)

  • 我认为这种情况可以用以下方式捕获:(crontab -l 2&gt; / dev / null; echo ... (2认同)

rog*_*ack 5

这是另一种避免重复的单行方式

(crontab -l 2>/dev/null | fgrep -v "*/1 *  *  *  * your_command"; echo "*/1 *  *  *  * your_command") | crontab -
Run Code Online (Sandbox Code Playgroud)

这是一种执行 JohnZ 的回答并避免no crontab for user消息的方法,或者如果您需要在set -eu类型环境中操作并且不能让任何内容返回失败(在这种情况下,该2>/dev/null部分是可选的):

( (crontab -l 2>/dev/null || echo "")  ; echo "0 * * * * your_command") | sort -u - | crontab -
Run Code Online (Sandbox Code Playgroud)

或者,如果您想将内容分开以便它们更具可读性:

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -
Run Code Online (Sandbox Code Playgroud)

或者可以选择删除对 your_command 的任何引用(例如:如果计划已更改,您只希望它执行一次)。在这种情况下,我们不再需要uniq(增加奖金,插入顺序也被保留):

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
preceding_cron_jobs=$(echo "$preceding_cron_jobs" | grep -v your_command )
(echo "$preceding_cron_jobs" ; echo "$new_job") | crontab -
Run Code Online (Sandbox Code Playgroud)