Tutorial :How to create a cron job using Bash automatically without the interactive editor?



Question:

Does crontab have an argument for creating cron jobs without using the editor (crontab -e). If so, What would be the code create a cronjob from a Bash script?


Solution:1

You can add to the crontab as follows:

#write out current crontab  crontab -l > mycron  #echo new cron into cron file  echo "00 09 * * 1-5 echo hello" >> mycron  #install new cron file  crontab mycron  rm mycron  

Cron line explaination

* * * * * "command to be executed"  - - - - -  | | | | |  | | | | ----- Day of week (0 - 7) (Sunday=0 or 7)  | | | ------- Month (1 - 12)  | | --------- Day of month (1 - 31)  | ----------- Hour (0 - 23)  ------------- Minute (0 - 59)  

Source nixCraft.


Solution:2

You may be able to do it on-the-fly

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -  

crontab -l lists the current crontab jobs, cat prints it, echo prints the new command and crontab - adds all the printed stuff into the crontab file. You can see the effect by doing a new crontab -l.


Solution:3

This shorter one requires no temporary file, it is immune to multiple insertions, and it lets you change the schedule of an existing entry.

Say you have these:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"  cronjob="0 */15 * * * $croncmd"  

To add it to the crontab, with no duplication:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -  

To remove it from the crontab whatever its current schedule:

( crontab -l | grep -v -F "$croncmd" ) | crontab -  

Notes:

  • grep -F matches the string literally, as we do not want to interpret it as a regular expression
  • We also ignore the time scheduling and only look for the command. This way; the schedule can be changed without the risk of adding a new line to the crontab


Solution:4

Thanks everybody for your help. Piecing together what I found here and elsewhere I came up with this:

The Code

command="php $INSTALL/indefero/scripts/gitcron.php"  job="0 0 * * 0 $command"  cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -  

I couldn't figure out how to eliminate the need for the two variables without repeating myself.

command is obviously the command I want to schedule. job takes $command and adds the scheduling data. I needed both variables separately in the line of code that does the work.

Details

  1. Credit to duckyflip, I use this little redirect thingy (<(*command*)) to turn the output of crontab -l into input for the fgrep command.
  2. fgrep then filters out any matches of $command (-v option), case-insensitive (-i option).
  3. Again, the little redirect thingy (<(*command*)) is used to turn the result back into input for the cat command.
  4. The cat command also receives echo "$job" (self explanatory), again, through use of the redirect thingy (<(*command*)).
  5. So the filtered output from crontab -l and the simple echo "$job", combined, are piped ('|') over to crontab - to finally be written.
  6. And they all lived happily ever after!

In a nutshell:

This line of code filters out any cron jobs that match the command, then writes out the remaining cron jobs with the new one, effectively acting like an "add" or "update" function. To use this, all you have to do is swap out the values for the command and job variables.


Solution:5

EDIT (fixed overwriting):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -  


Solution:6

There have been a lot of good answers around the use of crontab, but no mention of a simpler method, such as using cron.

Using cron would take advantage of system files and directories located at /etc/crontab, /etc/cron.daily,weekly,hourly or /etc/cron.d/:

cat > /etc/cron.d/<job> << EOF  SHELL=/bin/bash   PATH=/sbin:/bin:/usr/sbin:/usr/bin   MAILTO=root HOME=/    01 * * * * <user> <command>  EOF  

In this above example, we created a file in /etc/cron.d/, provided the environment variables for the command to execute successfully, and provided the user for the command, and the command itself. This file should not be executable and the name should only contain alpha-numeric and hyphens (more details below).

To give a thorough answer though, let's look at the differences between crontab vs cron/crond:

crontab -- maintain tables for driving cron for individual users  

For those who want to run the job in the context of their user on the system, using crontab may make perfect sense.

cron -- daemon to execute scheduled commands  

For those who use configuration management or want to manage jobs for other users, in which case we should use cron.

A quick excerpt from the manpages gives you a few examples of what to and not to do:

/etc/crontab and the files in /etc/cron.d must be owned by root, and must not be group- or other-writable. In contrast to the spool area, the files under /etc/cron.d or the files under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly may also be symlinks, provided that both the symlink and the file it points to are owned by root. The files under /etc/cron.d do not need to be executable, while the files under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly do, as they are run by run-parts (see run-parts(8) for more information).

Source: http://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

Managing crons in this manner is easier and more scalable from a system perspective, but will not always be the best solution.


Solution:7

Chances are you are automating this, and you don't want a single job added twice. In that case use:

CRON="1 2 3 4 5 /root/bin/backup.sh"  cat < (crontab -l) |grep -v "${CRON}" < (echo "${CRON}")  

This only works if you're using BASH. I'm not aware of the correct DASH (sh) syntax.


Solution:8

A variant which only edits crontab if the desired string is not found there:

CMD="/sbin/modprobe fcpci"  JOB="@reboot $CMD"  TMPC="mycron"  grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")  


Solution:9

For a nice quick and dirty creation/replacement of a crontab from with a BASH script, I used this notation:

crontab <<EOF  00 09 * * 1-5 echo hello  EOF  


Solution:10

If you're using the Vixie Cron, e.g. on most Linux distributions, you can just put a file in /etc/cron.d with the individual cronjob.

This only works for root of course. If your system supports this you should see several examples in there. (Note the username included in the line, in the same syntax as the old /etc/crontab)

It's a sad misfeature in cron that there is no way to handle this as a regular user, and that so many cron implementations have no way at all to handle this.


Solution:11

No, there is no option in crontab to modify the cron files.

You have to: take the current cron file (crontab -l > newfile), change it and put the new file in place (crontab newfile).

If you are familiar with perl, you can use this module Config::Crontab.

LLP, Andrea


Solution:12

Here is a bash function for adding a command to crontab without duplication

function addtocrontab () {    local frequency=$1    local command=$2    local job="$frequency $command"    cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -  }  addtocrontab "0 0 1 * *" "echo hello"  


Solution:13

script function to add cronjobs. check duplicate entries,useable expressions * > "

cronjob_creator () {           # usage: cronjob_creator '<interval>' '<command>'      if [[ -z $1 ]] ;then      printf " no interval specified\n"  elif [[ -z $2 ]] ;then      printf " no command specified\n"  else      CRONIN="/tmp/cti_tmp"      crontab -l | grep -vw "$1 $2" > "$CRONIN"      echo "$1 $2" >> $CRONIN      crontab "$CRONIN"      rm $CRONIN  fi  }  

tested :

$ ./cronjob_creator.sh '*/10 * * * *' 'echo "this is a test" > export_file'  $ crontab  -l  $ */10 * * * * echo "this is a test" > export_file  

source : my brain ;)


Solution:14

CRON="1 2 3 4 5 /root/bin/backup.sh"   cat < (crontab -l) |grep -v "${CRON}" < (echo "${CRON}")  

add -w parameter to grep exact command, without -w parameter adding the cronjob "testing" cause deletion of cron job "testing123"

script function to add/remove cronjobs. no duplication entries :

cronjob_editor () {           # usage: cronjob_editor '<interval>' '<command>' <add|remove>    if [[ -z "$1" ]] ;then printf " no interval specified\n" ;fi  if [[ -z "$2" ]] ;then printf " no command specified\n" ;fi  if [[ -z "$3" ]] ;then printf " no action specified\n" ;fi    if [[ "$3" == add ]] ;then      # add cronjob, no duplication:      ( crontab -l | grep -v -F -w "$2" ; echo "$1 $2" ) | crontab -  elif [[ "$3" == remove ]] ;then      # remove cronjob:      ( crontab -l | grep -v -F -w "$2" ) | crontab -  fi   }   cronjob_editor "$1" "$2" "$3"  

tested :

$ ./cronjob_editor.sh '*/10 * * * *' 'echo "this is a test" > export_file' add  $ crontab  -l  $ */10 * * * * echo "this is a test" > export_file  


Solution:15

You can probably change the default editor to ed and use a heredoc to edit.

EDITOR=ed  export EDITOR    crontab -e << EOF  > a  > * * * * * Myscript  > * * * * * AnotherScript  > * * * * * MoreScript  > .  > w  > q  > EOF  

Note the leading > in that code means the return/enter key is pressed to create a new line.

The a means APPEND so it will not overwrite anything.

The . means you're done editing.

The w means WRITE the changes.

The q means QUIT or exit ed.

you can check it out

crontab -l  

You can delete an entry too.

EDITOR=ed  export EDITOR    crontab -e << EOF  > /Myscript/  > d  > .  > w  > q  > EOF  

That will delete the crontab entry with Myscript in it.

The d means delete the pattern inside the / /.

No check it again

crontab -l  

This solution works inside a script too less the > of course :-)


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »