How can I programmatically create a new cron job?

2019-01-05 08:53发布

I want to be able to programatically add a new cron job, what is the best way to do this?

From my research, it seems I could dump the current crontab and then append a new one, piping that back into crontab:

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

Is there a better way?

标签: linux unix cron
16条回答
SAY GOODBYE
2楼-- · 2019-01-05 09:49

Adding to JohnZ's answer, here's the syntax to schedule as root if you are a sudoer:

(sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | sudo crontab -
查看更多
Explosion°爆炸
3楼-- · 2019-01-05 09:50

You could also edit the cron table text file directly, but your solution seems perfectly acceptable.

查看更多
姐就是有狂的资本
4楼-- · 2019-01-05 09:52

Assuming that there is already an entry in your crontab, the following command should work relatively well. Note that the $CMD variable is only there for readability. Sorting before filtering duplicates is important, because uniq only works on adjacent lines.

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

If you currently have an empty crontab, you will receive the following error to stderr:

no crontab for user

If you want to avoid this, you can add a little bit of complexity add do something like this:

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -
查看更多
叛逆
5楼-- · 2019-01-05 09:52

Here's another one-liner way, that avoids duplicates

(crontab -l 2>/dev/null | fgrep -v "*/1 *  *  *  * your_command"; echo "*/1 *  *  *  * your_command") | crontab -

And here's a way to do JohnZ's answer and avoid no crontab for user message, or if you need to operate in a set -eu type environment and can't have anything return a failure (in which case the 2>/dev/null part is optional):

( (crontab -l 2>/dev/null || echo "")  ; echo "0 * * * * your_command") | sort -u - | crontab -

Or if you want to split things up so that they're more readable:

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -

Or optionally remove any references to your_command (ex: if the schedule has changed, you only want it ever cron'ed once). In this case we no longer need uniq (added bonus, insertion order is also preserved):

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 -
查看更多
登录 后发表回答