I need to add a cron job thru a script I run to set up a server. I am currently using Ubuntu. I can use crontab -e
but that will open an editor to edit the curr
Here is how to modify cron a entry without directly editing the cron file (which is frowned upon).
crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -
If you want to remove a cron entry, use this:
crontab -l -u <user> | sed '/find/d' | crontab -u <user> -
I realize this is not what gaurav was asking for, but why not have all the solutions in one place?
Well /etc/crontab
just an ascii file so the simplest is to just
echo "*/15 * * * * root date" >> /etc/crontab
which will add a job which will email you every 15 mins. Adjust to taste, and test via grep
or other means whether the line was already added to make your script idempotent.
On Ubuntu et al, you can also drop files in /etc/cron.*
which is easier to do and test for---plus you don't mess with (system) config files such as /etc/crontab
.
I have written a crontab deploy tool in python: https://github.com/monklof/deploycron
pip install deploycron
Install your crontab is very easy, this will merge the crontab into the system's existing crontab.
from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")
(I don't have enough reputation to comment, so I'm adding at as an answer: feel free to add it as as comment next to his answer)
Joe Casadonte's one-liner is perfect, except if you run with set -e
, i.e. if your script is set to fail on error, and if there are no cronjobs yet. In that case, the one-liner will NOT create the cronjob, but will NOT stop the script. The silent failure can be very misleading.
The reason is that crontab -l
returns with a 1
return code, causing the subsequent command (the echo
) not to be executed... thus the cronjob is not created. But since they are executed as a subprocess (because of the parenthesis) they don't stop the script.
(Interestingly, if you run the same command again, it will work: once you have executed crontab -
once, crontab -l
still outputs nothing, but it doesn't return an error anymore (you don't get the no crontab for <user>
message anymore). So the subsequent echo
is executed and the crontab is created)
In any case, if you run with set -e
, the line must be:
(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -
As a correction to those suggesting crontab -l | crontab -
: This does not work on every system. For example, I had to add a job to the root crontab on dozens of servers running an old version SUSE (don't ask why). Old SUSEs prepend comment lines to the output of crontab -l
, making crontab -l | crontab -
non-idempotent (Debian recognizes this problem in the crontab manpage and patched its version of Vixie Cron to change the default behaviour of crontab -l
).
To edit crontabs programmatically on systems where crontab -l
adds comments, you can try the following:
EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -
EDITOR=cat
tells crontab to use cat
as an editor (not the usual default vi), which doesn't change the file, but instead copies it to stdout. This might still fail if crontab -
expects input in a format different from what crontab -e
outputs. Do not try to replace the final crontab -
with crontab -e
- it will not work.
In Ubuntu and many other distros, you can just put a file into the /etc/cron.d
directory containing a single line with a valid crontab entry. No need to add a line to an existing file.
If you just need something to run daily, just put a file into /etc/cron.daily
. Likewise, you can also drop files into /etc/cron.hourly
, /etc/cron.monthly
, and /etc/cron.weekly
.