User Tools

Site Tools


If you want to send us your comments, please do so. Thanks
More on comments


Main rule

Always put the code in a script
Start the script with

#! /bin/bash

Then call the script from cron. If you do not you can get something like

/bin/sh: 1: [[: not found

in the case you used an [[ statement for example

cron mail filter: cron-deja-vu


man 8 cron
man 1 crontab
man 5 crontab
man 8 run-parts

Environment variables

LOGNAMEMay NOT be changed
MAILTO=useruser to send the output email to
SHELL=/bin/bashThe default shell is “/bin/sh”
DISPLAY=:0Define the display for GUI output
XAUTHORITY=/home/user/.XauthorityNeeded for DISPLAY
XDG_RUNTIME_DIR=“/run/user/1000”Needed for DISPLAY

dow (day of the week)

0 or 7 Sun(day)
Use the day of the week number, the full day name or the three letter shortended version like in the sunday options example above or have a look in this table

0   Sun  SUN    Sunday
1   Mon  MON    Monday
2   Tue  TUE    Tuesday
3   Wed  WED    Wednesday
4   Thu  THU    Thursday
5   Fri  FRI    Friday
6   Sat  SAT    Saturday
7   Sun  SUN    Sunday

A reference: Crontab day of the week syntax

Output to GUI

Add to the cron envrironment variables (crontab -e)


Works for

/usr/bin/xmessage Helloxmessage
/usr/bin/notify-send Hello

Or do something like

/bin/bash -c 'DISPLAY=:0 /usr/bin/xmessage Hello'

This does not work

/bin/bash -c 'DISPLAY=:0 /usr/bin/notify-send Hello'



When a script is ran from cron all echo output is send to the user via an e-mail
The e-mail address can be set with MAILTO=user@hostname or MAILTO=name@somedomain.tld
MAILTO=user@$HOSTNAME does not work
Put the MAILTO statement above the # m h dom mon dow command line

Output redirection to e-mail

Send output of a cron job to a specific user

7 * * * * | mail -s "Subject"

Output redirection to a file

Send output to a file

7 * * * *  somescript 2>&1 >> $HOME/cron.log
7 * * * *  somescript >> $HOME/cron.log 2>&1

Do not send the output anywhere

7 * * * * somescript >/dev/null 2>&1

File locations

User cron. The result is saved in /var/spool/cron/crontabs/

crontab -e

Sytem wide cron. Each entry also needs a username after the 5 time and date positions


General cron


Fixed time files


cron options file


systemd cron unit file


init cron deamon file



  • Jobs can be missed on systems which are not on 24 hours a day. In that case use anacron. To run anacron jobs in user mode
  • Via cron it is not possible to display a message, like a message with xmessage

32 / 64 bit computers

It seems that cron has different behaviour on an 32 bit Debian system and an 64 bit Debian system

cli differences to cron


This command has to be run as root
When run from a normal cron job it results in an error
If run as

sudo chown user:user folder/

it works if

user     ALL=(root:ALL) NOPASSWD:/bin/chown *\:* *

is added to the sudoers file. Do this as root with



When using the -e option it only works fine in a script. Make sure to add #! /bin/bash at the first line of the script
When echo -e is used it is needed to do “\” expansion on the commandline and in scripts, not in cron
In cron -e is not needed, if used it will be displayed as literal -e. This works fine:

36,38 * * * * echo "Some test\t\t$(date)" >> $HOME/crontest.txt

The echo output in a script in the e-mail cron sends is the same for

echo -e "Some text"
echo -e "\033[01;46;37mSome text\033[00m"


date +'%s'
date "+%s"
echo -e "\nDone at $(date +'%s') which is at $(date +'%d-%b-%Y %H:%M UTC')"


cron does not know about the user. So the $USER variable is empty. Demonstration: Add to cron:

* * * * * echo -e "$(date)\tuser: $USER" >> $HOME/crontest.txt

Check crontest.txt after a few minutes
Do not forget to turn this cronjob off after testing :-)

Getting the username of the user on whose behave cron has executed the job can be achieved by using

USERcron=$(whoami) # The user who ran the script or on whose behave cron has ran

or with

USERcron=$(echo $HOME | cut -d / -f 3)

This works for both root and a normal user
Make sure to define user in every file called by an other file


USERcron=$(id -u)

holds the user in cron. Only it is the numeric representation root being 0 and the first added user mostly 1000

Check if a script is run from cron or started by a user


Proof of concept

#! /bin/bash
USERcron=$(whoami) # The user who ran the script or on whose behave cron has ran.
                      # This works for both root and a normal user, interactive or ran from cron.
echo "user_whoami: $user_whoami"
echo USER: $USER # When ran interactive $USER has a value. When ran from cron $USER is empty
if [[ -z $USER ]]; then # USER is an empty string so ran from cron
  interactive=1		#No, the script is initiated by cron
  echo -e "User is: $USER\tinteractive is: $interactive"
  echo -e "Ran from Cron"
else	# Double check
  if [[ -n $USER ]]; then # USER is a normal user. The sting is not empty
    interactive=0	#Yes, the script is initiated by the user
		echo -e "User is: $USER\tinteractive is: $interactive"
    echo -e "Initiated by the user, not ran from Cron"
    echo Strange error when determining who ran this script

Use a variable

This does not work if you want to read calledfromcron in the variable unkown, its value is empty. nice -n 19 is just there for the demo

  cron entry: * 20 23 6 2 export CALLEDFROMCRON=1; nice -n 19 echo Hallo from cron. calledfromcron is: $calledfromcron; $HOME/; export CALLEDFROMCRON=0

This works. The sleep 20 command is added so /tmp/calledfromcron.txt is removed when $HOME/ has probably finished execution. Not a perfect solution but it might work in certain cases

  cron entry: * 21 23 6 2 echo "calledfromcron" > /tmp/calledfromcron.txt; $HOME/; sleep 20; rm -f /tmp/calledfromcron.txt
  cron entry: * 21 23 6 2 touch /tmp/calledfromcron.txt; $HOME/; sleep 20; rm -f /tmp/calledfromcron.txt

Use ps

Thanks to Sebastiaan
The Z is added to avoid comparison of empty strings which will give an error
The “ are added to avoid misinterpretation of spaces

if [ "Z$(ps o comm="" -p $(ps o ppid="" -p $$))" == "Zcron" -o \
      "Z$(ps o comm="" -p $(ps o ppid="" -p $(ps o ppid="" -p $$)))" == "Zcron" ]
     echo "Called from cron on $(date)" >> ~/test.txt
     echo "Not called from cron on $(date)" >> ~/test.txt

This does not work

Just for reference:
Check if $- includes the i flag. The i is set for interactive shells
If cron is running the i is not present. But also when this is implemented in a script, that is ran from the command line, it is in non interactive mode so the i flag is not set also
You can from the commandline and as a command in cron

  echo Flags: $-
  if [[ $- == *i* ]]; then echo i flag is present; fi

You can run this script form the commandline and with cron

#! /bin/bash
case "$-" in
if [[ $INTERCACTIVE -eq 0 ]]; then
    touch $HOME/not_interactive.txt
if [[ $INTERCACTIVE -eq 1 ]]; then
    echo "Interactive"


bad minute

After saving and closing the file opened with crontab -e

$ crontab -e
crontab: installing new crontab
"/tmp/crontab.abcde/crontab":20: bad minute
errors in crontab file, can't install.
Do you want to retry the same edit? (y/n) y
crontab: installing new crontab

20 is the linenumber the error is found on
This happenes when you want to split long lines with a \
Extra spaces to line out the code of the command are allowed

redirection unexpected

/bin/sh: 1: Syntax error: redirection unexpected

Solution: write a script and execute it with cron

Crontabs reboot only works for root
Cron settings aid
Ubuntu cron howto

Main subjects on this wiki: Linux, Debian, HTML, Microcontrollers, Privacy

Privacy statement
Bugs statement
Copyright © : 2014 - 2022 and the authors
Changes reserved.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
cron.txt · Last modified: 24-04-2022 10:00 by wim