Error in crontab entry - cron

I have been trying to make a cron entry for a shell script:
50 */4 * * * /path/script-file.sh > /dev/null 2>&1
aimed to run the script at HH:50 at a frequency of 4 hours. But this errors out with the message:
crontab: error on previous line; unexpected character found in line.
crontab: errors detected in input, no crontab file generated.
I removed the "/4" and the error vanished, but I know that cron does allow this format. Does anybody know what the issue could be?
Thank you very much for any help.

Some cron implementations don't support steps (e.g. */4) - check man 5 crontab on your particular system.
You can use the list 0,4,8,12,16,20 instead.
Off-topic: If you are using bash, you could probably replace > /dev/null 2>&1 with the shorter &>/dev/null or just close stdout and stderr with 1>&- 2>&-. (see #Keith Thompson's comment below)

Related

Crontab how to disable emails

I want to disable email reports on some tasks which run frequently. I've gone through the following links
https://unix.stackexchange.com/questions/84335/stop-cron-sending-mail-for-backup-script
https://www.cyberciti.biz/faq/disable-the-mail-alert-by-crontab-command/
They suggest adding >/dev/null 2>&1 at the end of the command to disable emails.
This is my crontab entry :
* * * * * /bin/bash /home/ubuntu/startup/monitor-mosquitto.sh >/dev/null 2>&1
But I'm still receiving emails every time the script is run. In fact, not just once but I get like 8-15 mails every time it runs.
Am I doing anything wrong here ? BTW, I'm using crontab as root ( sudo crontab -e )
See man 5 crontab:
If MAILTO is defined but empty (MAILTO=""), no mail will be sent.
If memory serves, I have used that on the line itself, or preceding it:
MAILTO=""
* * * * * /bin/bash /home/ubuntu/startup/monitor-mosquitto.sh
Note that this will affect all lines that follow it so you may want to place it last, or renable MAILTO.
Also, strictly speaking, you should be able to work out what you did with shell redirection in the shell itself. What you have looks correct so I am a little puzzled. Maybe make sure to test it as root not as you.

bash script not working as expected when executed with cron [duplicate]

I have a strange problem of being to able to run a bash script from commandline but not from the crontab entry for root. I am running Ubuntu 12.04.
* * * * 1-5 root /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log
If I run the script from the cmd line using bash, it works fine but sh fails with following error:
> jmeter-cron-randomise.sh: 7: jmeter-cron-randomise.sh: arithmetic
> expression: expecting primary: " % 1 "
Having googled the problem, it seems like standard shell doesn't have the same math operators, like % (modulus), as bash. I'm Not sure why the cron job is failing in the script? I am assuming it is because it's not using the bash shell? It's definitely being fired by the cron daemon (can see it in /var/log/syslog). Any help much appreciated.
You likely need to tell cron that the shell to use is the bash shell as it defaults to sh. You can do that for all crontab entries by putting this line in your crontab:
SHELL=/bin/bash
Note that this will cause all scripts in the crontab to be run under bash which may not be what you want. If you want to change the crontab line itself to just run bash, change it to this:
* * * * 1-5 root /bin/bash /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log 2>&1
Note that I have also caused stderr to be written to the cron.log file (2>&1) which may not be what you want but is pretty common practice. This may help you further diagnose errors from the script.
In case this helps anyone: for me this appeared to be because I had ended up with "DOS" line endings (CR-LF) instead of "unix" line endings (LF). This can be checked using od or your favourite hex dump tool, e.g.:
od -c <script_file>
... and look for \r\n instead of just \n.
It seems (and this article supports it) that the CR character stops the "shebang" from working because it's interpreted as part of the shell executable's filename.
(The line endings themselves appeared because the file came from a git repository and was transferred via a Windows machine).
I also encountered this problem trying to schedule a database backup as root and it made me pull my hair out! I was working on a CentOS 7 box.
Whenever I would check /var/spool/mail/root I would see a log:
sh: root: command not found, yet the command would run perfectly in the terminal.
This is what worked for me:
I created the crontab entry using crontab -e while logged in as root.
Using the command above as an example:
* * * * 1-5 root /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log
I deleted the root user entry like:
* * * * 1-5 /home/xxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/jmeter-cron-randomise.sh >> /home/xxxxxxx/jmeter/VerificationService-0.0.1-SNAPSHOT/cron.log
That solved my problem.

How to print the output of running program started by crontab job to a file on daily basis

A script start.sh is registered in crontab to run on daily basis
But I'd like to save the output of the program to a file, like cronlog-yyyyMMdd.log
I tried the following but failed:
16 10 * * 1-5 ~/start.sh >> ~/cronlog/$(date+"\%F")-cron.log 2>&1
Anyone help me?
Using fully-qualified paths to all programs and files that are mentioned eliminate a whole class of errors from debugging issues with crontab entries. In this particular case, doing so would have only proved there were no problems with PATH issues in your crontab entry.
Your issue is that you need a space char between the date cmd and it's formatting argument string, instead of
$(date+"\%F")
#0 ^v
$(date +"\%F")
I commend you for your good crontab debug etiquette; capturing std-err and std-out to a file gives you 1. proof that your command ran when you expected it to (or if you have an error in your time specification, it will show you when the cmd did run). 2. you avoid having your localhost email box filling up with msgs from the cron daemon. 3 Any std-err msgs that were generated are also captured and are in generally in sync and time order with std-out messages.
IHTH.
16 10 * * 1-5 ~/start.sh >> ~/cronlog/$(date +"\%F")-cron.log
Edit: as explained in comments, this answers the question by correcting a typo in the asker's attempted entry

crontab doesnt work in linux

My Linux version is red hat enterprise linux server release 5.3 tikanga
i have schedule crontab as below
1 * * * * /usr/testjob.sh 2>&1 >> /usr/result.txt
crontab job not running on scheduled time...
Please suggest..
Try this at first.
* * * * * /usr/testjob.sh
Then you may received a mail for every minutes. Check the error output.
Sometimes, it may caused by your default shell is just sh instead of bash.
So, maybe ">>" is not supported.
You should check do you have /usr permission when you want to write into it.
As said by +Shawn Chin, if you want to run your command only once, the at command is your friend.
If you want to run your command repeatedly, then you are right to use the cron framework. The manual page explaining the fields of the crontab may be obtained with the following command:
$ man -s 5 crontab
You appear to be in an Indian time-zone (IST). You may have to specify that into the crontab. For instance, using the 'crontab -e' command (to save and quit, type 'ESC-wq', as the editor is VI by default):
#
CRON_TZ=IST
# run at 06:33 (am), every day
33 06 * * * /usr/testjob.sh >> /usr/result.txt 2>&1
Note that '2>&1' should be placed AFTER '>> /usr/result.txt', not before.
just to mention it and make sure
NOTE: Each cron table entry must have a trailing line break in order
for the cron table entry to be recognized.

Test run cron entry

I added a cron job recently, but made a mistake in the path while giving the command and hence, the job never succeeded. Is there some way to test the cron changes we have done?
Please note that I had indeed copied and pasted the command from my command line and it was just an stray keypress that caused this.
When I want to test my cron jobs I usually set the interval very low and monitor the logs closely. When I am convinced the entry is correct, I set the interval back to a sane value.
For example, run job every two minutes:
*/2 * * * * echo "Hello World"
And the I run tail -f on my log file (/var/log/syslogon debian).
This question has also been asked on serverfault and has garnered a couple additional answers
The following is a paraphrased version of Marco's solution:
(Not sure if best etiquette is not providing a link only answer or not copying someone else's solution)
Create a environment file with a temporary cron entry
* * * * * /usr/bin/env > /home/username/cron-env
Then create a shell script called run-as-cron which executes the command using that environment.
#!/bin/sh
. "$1"
exec /usr/bin/env -i "$SHELL" -c ". $1; $2"
Give it execute permission
chmod +x run-as-cron
and then it is then used like this:
./run-as-cron <cron-environment> <command>
e.g.
./run-as-cron /home/username/cron-env 'echo $PATH'
Joshua's answer does not work for me. Two problems:
Variables in cron-env file are not exported (set -a needed).
Script is still tied to current tty (setsid needed).
The script run-as-cron should be
#!/bin/sh
. "$1"
exec setsid /usr/bin/env -i "$SHELL" -c "set -a; . $1; $2" </dev/null
Not enough rep' to fix his answer or add a comment...
use command crontab -e
This will open a vim editor and all you got to do here is
* * * * * /somepath/urscript.sh , make sure you have the appropriate spaces between dates and the path of the script
After the execution , you can check in the /var/spool/mail there will a complete trail of the script execution or errors.
For testing there is no way .. but in case ur sh urscript.sh works then cron tab will have no problem as it is exactly same thing what u do manually.

Resources