Search code examples
linuxubuntucroncron-task

How to add a new task in crontab using a script


I need to use crontab to add new tasks to be done at a certain time. I need to add these tasks using a script. I will do something like:

echo "command" >> /etc/crontab

But I know that this crontab file is just for root user, so I need to use:

crontab -e

to open my own list of tasks. The problem is the previous command opens a temporary file and I can't locate it. (It has a random name in /tmp or something?) I will do something like:

echo "5 5 5 5 5 user command" | crontab -e

to write a new line in my own crontab list but this doesn't work.

Am I wrong in something? Does anyone has an idea for solving this? I'm using Ubuntu.


Solution

  • You are having difficulty with your current approach because crontab -e doesn't read from stdin. However, crontab without the -e switch, does read from stdin.

    The most obvious way is to just append the new cron job to the existing crontab:

    crontab -l > current_cron
    cat >> current_cron << EOF
    # new cron job here
    EOF
    crontab < current_cron
    rm -f current_cron
    

    The obvious issue with this approach is that there is no check to see if the cron job exists already. That's where it can get a little tricky.

    One way to tackle that would be to have a "script managed section" in crontab, typically, at the bottom:

    # DO NOT MODIFY THE SECTION BELOW MANUALLY.  IT'S MANAGED BY AUTOMATION.
    #---script managed section---
    "cron job 1"
    "cron job 2"
    

    Then, a script can manage this section - it is best to have a single script that manages all automatic cron jobs:

    crontab -l > current_cron
    sed '/---script managed section---/q' current_cron > new_cron
    cat >> new_cron << EOF
    # updated cron jobs here
    EOF
    crontab < new_cron
    rm -f new_cron current_cron
    

    If we need even more fine-grained control, then we can have a section for each managed cron job, with begin and end markers and make the script deal with a specific section each time.

    However, there is a better idea for Ubuntu. We can completely do away with crontab and use /etc/cron.d instead. Here, we have one file for each cron job which follows the exact format of a cron job spec. Since there is a 1:1 correspondence between cron jobs and /etc/cron.d files, they are managed directly as files rather than through crontab command and hence, automation is much easier.

    From man cron on Ubuntu:

    In Debian, cron reads the files in the /etc/cron.d directory. cron treats the files in /etc/cron.d as in the same way as the /etc/crontab file (they follow the special format of that file, i.e. they include the user field). However, they are independent of /etc/crontab: they do not, for example, inherit environment variable settings from it. This change is specific to Debian.