If you want to send us your comments, please do so. Thanks
More on comments
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
Variable | Remark |
---|---|
HOME | |
LOGNAME | May NOT be changed |
MAILTO=user | user to send the output email to |
PATH | |
SHELL=/bin/bash | The default shell is “/bin/sh” |
DISPLAY=:0 | Define the display for GUI output |
XAUTHORITY=/home/user/.Xauthority | Needed for DISPLAY |
XDG_RUNTIME_DIR=“/run/user/1000” | Needed for DISPLAY |
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
Add to the cron envrironment variables (crontab -e)
DISPLAY=:0 #DISPLAY=:0.0 XAUTHORITY=/home/user/.Xauthority
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
Send output of a cron job to a specific user
7 * * * * somescript.sh | mail -s "Subject" name@e-mailprovider.com
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
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
/etc/crontab
General cron
/etc/cron.d
Fixed time files
/etc/cron.daily /etc/cron.weekly /etc/cron.monthly
cron options file
/etc/default/cron
systemd cron unit file
/etc/systemd/system/multi-user.target.wants/cron.service
init cron deamon file
/etc/init.d/cron
It seems that cron has different behaviour on an 32 bit Debian system and an 64 bit Debian system
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
visudo
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
Also
USERcron=$(id -u)
holds the user in cron. Only it is the numeric representation root being 0 and the first added user mostly 1000
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" else echo Strange error when determining who ran this script fi fi
This does not work if you want to read calledfromcron in somescript.sh 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/somescript.sh; export CALLEDFROMCRON=0
This works. The sleep 20 command is added so /tmp/calledfromcron.txt is removed when $HOME/somescript.sh 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/somescript.sh; sleep 20; rm -f /tmp/calledfromcron.txt cron entry: * 21 23 6 2 touch /tmp/calledfromcron.txt; $HOME/somescript.sh; sleep 20; rm -f /tmp/calledfromcron.txt
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
#!/bin/bash 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" ] then echo "Called from cron on $(date)" >> ~/test.txt else echo "Not called from cron on $(date)" >> ~/test.txt fi
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 *i*) INTERCACTIVE=1 ;; *) INTERCACTIVE=0 ;; esac if [[ $INTERCACTIVE -eq 0 ]]; then touch $HOME/not_interactive.txt fi if [[ $INTERCACTIVE -eq 1 ]]; then echo "Interactive" fi
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
/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
RSS
Disclaimer
Privacy statement
Bugs statement
Cookies
Copyright © : 2014 - 2022 Webevaluation.nl and the authors
Changes reserved.