Shell – Is it possible to write to the crontab from a multipurpose script

cronshell-script

When I want to manipulate Unix cron, I do

crontab -e

then type (or paste) my directives.

How do I paste directive to crontab directly from a script?

In other words: Instead of pasting content inside crontab -e, I want to paste and save it there from outside, ready from a script, so to automate things up.

I ask this regarding a multi-purpose script I run each time I create a new VPS environment (for example, new Digital Ocean droplet).


I can type to files via, for example:

sudo bash -c "touch /location/new_file && echo 'text...text...text...text' > /location/new_file

Or:

sudo cat <<EOF >> /location/new_file
text...
text...
text...
text...
EOF

Yet, I don't know if it is even possible to write directly to Crontab from a script, and how.

This is the task I would want to paste inside Cron tab — From a script:

0 8 * * *  tar -zcvf /home/USER/backups/files/www-html-$(date +\%F-\%T-).tar.gz /var/www/html
0 8 * * *  find /home/USER/backups/files/* -mtime +30 -exec rm {} \;

0 8 * * *  mysqldump -u benia -p121212 --all-databases > /home/USER/backups/mysql/alldb_backup.sql
1 8 * * *  tar -zcvf /home/USER/backups/mysql/alldb_backup-$(date +\%F-\%T-).sql.tar.gz /home/USER/backups/mysql/alldb_backup.sql
2 8 * * *  rm /home/USER/backups/mysql/alldb_backup.sql
2 8 * * *  find /home/USER/backups/mysql/* -mtime +30 -exec rm {} \;

Note:

The above cron task does 2 things:

  1. Daily backup all site-dirs and all sqls, into 2 different dirs: One is ~/backups/files and one is ~/backups/sql
  2. Find and delete files created 30 days ago — each day anew.

Best Answer

Per Ipor Sircer's answer about the usage of cron, i.e.

man crontab:

   crontab [ -u user ] file

   The  first  form  of this command is used to install a new crontab from
   some named file or standard  input  if  the  pseudo-filename  ``-''  is
   given.

this means that you send the lines you want in your crontab file, to the stdin of this command:

crontab -

crontab will recreate a new cron file containing those commands.

  1. The script will first print your existing crontab using crontab -u $user -l 2>/dev/null.
    you will need to assign the value of your user to $user or use $USER if its in your environment.

  2. It will print the new lines you want and capture the aggregated result into a pipe connected to stdin of crontab -.


Here's how it should look like in your general-purpose script:

#!/bin/bash

user=YOU_NEED_TO_ENTER_YOUR_USER_HERE

# use a subshell to capture both commands output into the pipe (    # prints the current value of crontab
    crontab -u $user -l 2>/dev/null

    # print your cron jobs to STDOUT    
    cat <<- 'EOF'
        0 8 * * *  tar -zcvf /home/USERNAME/backups/files/www-html-$(date +\%F-\%T-).tar.gz /var/www/html
        0 8 * * *  find /home/USERNAME/backups/files/* -mtime +30 -exec rm {} \;

        0 8 * * *  mysqldump -u benia -p121212 --all-databases > /home/USERNAME/backups/mysql/alldb_backup.sql
        1 8 * * *  tar -zcvf /home/USERNAME/backups/mysql/alldb_backup-$(date +\%F-\%T-).sql.tar.gz /home/USERNAME/backups/mysql/alldb_backup.sql
        2 8 * * *  rm /home/USERNAME/backups/mysql/alldb_backup.sql
        2 8 * * *  find /home/USERNAME/backups/mysql/* -mtime +30 -exec rm {} \;
    EOF

# Everything printed to stdout - inside the subshell will be connected
# to the pipe and feed to crontab on stdin - recreating a new crontab ) | crontab -
Related Question