可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have setup cronjob for root user in ubuntu environment as follows by typing crontab -e
34 11 * * * sh /srv/www/live/CronJobs/daily.sh
0 08 * * 2 sh /srv/www/live/CronJobs/weekly.sh
0 08 1 * * sh /srv/www/live/CronJobs/monthly.sh
But the cronjon do not run. I have tried checking if the cronjob is running using
pgrep cron
and that gives process id 3033.The shell scrip is calls python file and is used to send email. Running the python file is ok. There\'s no error in it but the cron doesn\'t run. The daily.sh file has following code in it.
python /srv/www/live/CronJobs/daily.py
python /srv/www/live/CronJobs/notification_email.py
python /srv/www/live/CronJobs/log_kpi.py
回答1:
WTF?! My cronjob doesn\'t run?!
Here\'s a checklist guide to debug not running cronjobs:
- Is the Cron daemon running?
- Run
ps ax | grep cron
and look for cron.
- Debian:
service cron start
or service cron restart
- Is cron working?
* * * * * /bin/echo \"cron works\" >> /tmp/file
- Syntax correct? See below.
- You obviously need to have write access to the file you are redirecting the output to. A unique file name in
/tmp
which does not currently exist should always be writable.
- Is the command working standalone?
- Check if the script has an error, by doing a dry run on the CLI
- when testing your command, test as the user whose crontab you are editing, which might not be your login or root
- Can cron run your job?
- Check
/var/log/cron.log
or /var/log/messages
for errors.
- Ubuntu:
grep CRON /var/log/syslog
- Redhat:
/var/log/cron
- Check permissions
- set executable flag on the command:
chmod +x /var/www/app/cron/do-stuff.php
- if you redirect the output of your command to a file, verify you have permission to write to that file/directory
- Check paths
- check she-bangs / hashbangs line
- do not rely on environment variables like PATH, as their value will likely not be the same under cron as under an interactive session
- Don\'t suppress output while debugging
- commonly used is this suppression:
30 1 * * * command > /dev/null 2>&1
- re-enable the standard output or standard error message output
Still not working? Yikes!
- Raise the cron debug level
- Debian
- in
/etc/default/cron
- set
EXTRA_OPTS=\"-L 2\"
service cron restart
tail -f /var/log/syslog
to see the scripts executed
- Ubuntu
- in
/etc/rsyslog.d/50-default.conf
- add or comment out line
cron.crit /var/log/cron.log
- reload logger
sudo /etc/init.d/rsyslog reload
- re-run cron
- open
/var/log/cron.log
and look for detailed error output
- Reminder: deactivate log level, when you are done with debugging
- Run cron and check log files again
Cronjob Syntax
# Minute Hour Day of Month Month Day of Week User Command
# (0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0 2 * * * root /usr/bin/find
This syntax is only correct for the root
user. Regular user crontab
syntax doesn\'t have the User field (regular users aren\'t allowed to run code as any other user);
# Minute Hour Day of Month Month Day of Week Command
# (0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0 2 * * * /usr/bin/find
Crontab Commands
crontab -l
- Lists all the user\'s cron tasks.
crontab -e
, for a specific user: crontab -e -u agentsmith
- Starts edit session of your crontab file.
- When you exit the editor, the modified crontab is installed automatically.
crontab -r
- Removes your crontab entry from the cron spooler, but not from crontab file.
回答2:
Finally I found the solution. Following is the solution:-
Never use relative path in python scripts to be executed via crontab.
I did something like this instead:-
import os
import sys
import time, datetime
CLASS_PATH = \'/srv/www/live/mainapp/classes\'
SETTINGS_PATH = \'/srv/www/live/foodtrade\'
sys.path.insert(0, CLASS_PATH)
sys.path.insert(1,SETTINGS_PATH)
import other_py_files
Never supress the crontab code instead use mailserver and check the mail for the user. That gives clearer insights of what is going.
回答3:
Another reason crontab will fail: Special handling of the %
character.
From the man file:
The entire command portion of the line, up to a newline or a
\"%\" character, will be executed by /bin/sh or by the shell specified
in the SHELL variable of the cronfile. A \"%\" character in the
command, unless escaped with a backslash (\\), will be changed into
newline characters, and all data after the first % will be sent to
the command as standard input.
In my particular case, I was using date --date=\"7 days ago\" \"+%Y-%m-%d\"
to produce parameters to my script, and it was failing silently. I finally found out what was going on when I checked syslog
and saw my command was truncated at the %
symbol. You need to escape it like this:
date --date=\"7 days ago\" \"+\\%Y-\\%m-\\%d\"
See here for more details:
http://www.ducea.com/2008/11/12/using-the-character-in-crontab-entries/
回答4:
I want to add 2 points that I learned:
- Cron config files put in /etc/cron.d/ should not contain a dot (.). Otherwise, it won\'t be read by cron.
- If the user running your command is not in /etc/shadow. It won\'t be allowed to schedule cron.
Refs:
- http://manpages.ubuntu.com/manpages/xenial/en/man8/cron.8.html
- https://help.ubuntu.com/community/CronHowto
回答5:
I\'ve found another reason for user\'s crontab not running: the hostname is not present on the hosts file:
user@ubuntu:~$ cat /etc/hostname
ubuntu
Now the hosts file:
user@ubuntu:~$ cat /etc/hosts
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
This is on a Ubuntu 14.04.3 LTS, the way to fix it is adding the hostname to the hosts file so it resembles something like this:
user@ubuntu:~$ cat /etc/hosts
127.0.0.1 ubuntu localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
回答6:
For me, the solution was that the file cron was trying to run was in an encrypted directory, more specifcically a user diretory on /home/. Although the crontab was configured as root, because the script being run exisited in an encrypted user directory in /home/ cron could only read this directory when the user was actually logged in. To see if the directory is encrypted check if this directory exists:
/home/.ecryptfs/<yourusername>
if so then you have an encrypted home directory.
The fix for me was to move the script in to a non=encrypted directory and everythig worked fine.
回答7:
I experienced same problem where crons are not running.
We fixed by changing permissions and owner by
Crons made root owner as we had mentioned in crontab AND
Cronjobs 644 permission given
回答8:
Sometimes the command that cron needs to run is in a directory where cron has no access, typically on systems where users\' home directories\' permissions are 700 and the command is in that directory.