5

Updated (and snipped) with more details below.

I've set up a cron script and I'm trying to debug why it's not running. [Snipped context testing, which is all ok; see revision 2 for details] The command itself, in case it helps, (arrows indicate line-wrapping for legibility) is:

/usr/bin/php -C /etc /path/to/process.php
↪  >>/path/to/stdout.log 2>>/path/to/stderr.log

[Snipped permissions testing, which is all ok; see below and revision 2 for details]

Checking crontab (again, wrapped for legibility), I get:

[blackero@XXXXXXXXXXX to]$ sudo crontab -u cronuser -l
MAIL="blackero@localhost"

30 9 * * * cronuser /usr/bin/php -C /etc /path/to/process.php
↪   >>/path/to/stdout.log 2>>/path/to/stderr.log
20 18 7 * * cronuser /usr/bin/php -C /etc /path/to/process.php
↪   >>/path/to/stdout.log 2>>/path/to/stderr.log
22 18 7 * * cronuser echo "Test" > /path/to/test.txt
↪   2> /path/to/error.txt

Update #1 at 2012-02-08 12:32 Z

[Snip: Having tried derobert's suggestion (revision 3)], I know that the cronuser can run the script properly and can write to the two .log files. (One of the first things the process.php script does is download a file by FTP; it is successfully doing that too.) But, even after fixing the MAIL="" line (both by removing it and by changing it to MAILTO="blackero@localhost"), the cron task still doesn't run, nor does it send me any email.

A friend suggested that I retry the

 9 12 8 * * cronuser /bin/echo "Test" > /var/www/eDialog/test.txt
 ↪  2> /var/www/eDialog/error.txt

task, after passing the full path to /bin/echo. Having just tried that, it also didn't work and also generated no email, so I'm at a loss.

Update #2 at 2012-02-08 19:15 Z

A very useful chat conversation with oHessling, it would seem that the problem is with pam. For each time that cron has tried to run my job, I have /var/log/cron entries:

crond[29522]: Authentication service cannot retrieve authentication info
crond[29522]: CRON (cronuser) ERROR: failed to open PAM security session: Success
crond[29522]: CRON (cronuser) ERROR: cannot set security context

I fixed that by adding the following line to /etc/shadow:

cronuser:*:15217:0:99999:7:::

As I found on a forum, if the user does not appear in /etc/shadow, then pam won't continue processing the security request. Adding * as the second column means this user cannot log in with a password (as no hash is specified). Fixing that led to a different error in /var/log/cron, so, double-checking my crontab I noticed I had specified the username each time.

Correcting that means my crontab now reads:

[blackero@XXXXXXXXXXX ~]$ sudo crontab -u cronuser -l
MAILTO="blackero@localhost"

30 9 * * * /usr/bin/php -C /etc /path/to/process.php
↪   >>/path/to/stdout.log 2>>/path/to/stderr.log
52 18 8 * * /usr/bin/php -C /etc /path/to/process.php
↪   >>/path/to/stdout.log 2>>/path/to/stderr.log
9 12 8 * * /bin/echo "Test" > /path/to/test.txt
↪   2> /path/to/error.txt

but now /var/log/cron shows me:

Feb  8 18:52:01 XXXXXXXXXXX crond[16279]: (cronuser) CMD (/usr/bin/php -C /etc
↪   /path/to/process.php >>/path/to/stdout.log 2>>/path/to/stderr.log)

and nothing comes into the stdout.log or the stderr.log. No mail was sent to me and none of the other files in /var/log/ has any entry in the right timeframe, and I'm running out of ideas as to where to look to see what's going wrong

  • When you say you put that line in "a cron file", which file in particular? That's the format for a system cron file (e.g., in /etc)—user crontabs don't have the user field. – derobert Feb 08 '12 at 19:08
  • I'm just typing a bigger update at the moment, but I noticed that myself (when I solved the pam issue, it was really obvious from /var/log/cron that this was the case). But I still haven't fixed. it. Update coming within a minute or two. – Owen Blacker Feb 08 '12 at 19:13
  • @derobert Updated now. – Owen Blacker Feb 08 '12 at 19:19
  • While nothing gets written to stdout.log and stderr.log, do they get created? If they're being created, then at least that part of the command is working; that'd narrow it down to PHP or the PHP script failing for some reason. In which case (a) make sure PHP is set to flush output (or call flush/ob_flush); (b) start putting <?php echo "about to frob" ?> lines in the script, and see how far it gets; (c) make sure PHP is set to spew errors to stderr—not just some error log (that it may not even have permission to under that user) – derobert Feb 09 '12 at 16:27
  • Also, su'd to cronuser, try echo hello | mail -s 'test message' your-user and see if that mail goes somewhere useful (just to make sure local mail is working on the box). – derobert Feb 09 '12 at 16:30
  • The PHP script worked when I ran it in a minimal shell as cronuser earlier in the week (and was sending output to both stdout and stderr before I tweaked it), but I'll try testing mail when I get to the office tomorrow; thanks :o) – Owen Blacker Feb 09 '12 at 23:48
  • Mail is indeed working on the box; having just done my sudo su -s /bin/sh cronuser and echo hello | mail -s 'test message' blackero, I do end up with a message in my mailbox. The two files stdout.log and stderr.log already exist (from having run the script in a minimal shell, per your earlier suggestion), so I know it's not the PHP script that's the problem; it's something about the configuration of cron (presumably). That test also confirmed that the PHP output does go to stdout and stderr, rather than some other log. – Owen Blacker Feb 10 '12 at 13:58
  • I've found the problem. And I feel stupid: see below – Owen Blacker Feb 10 '12 at 16:28

3 Answers3

6

First off, when a cron job fails, cron sends email. By default, that is to the owner of the cron job. So those emails are probably going to cronuser@localhost or maybe root@localhost. Check those email boxes. Alternatively, you can specify where the mail should go by putting MAILTO=email@domain at the top of the crontab file. (Actually, I see you put MAIL="" at the top of your crontab. At least according to man 5 crontab on my machine, it should be MAILTO. And you don't want to throw away error messages when trying to figure out why it isn't working!)

Second, cron uses /bin/sh. Set SHELL=/bin/bash (again, at the top of the crontab) if you need bash extensions.

Third, you haven't fully tested permissions. You need to do something like:

# su -s /bin/sh -u cronuser
$ touch /path/to/stdout.log
$ touch /path/to/stderr.log
$ cat /path/to/process.php > /dev/null
$ exit

to fully check permissions. cronuser could be missing +x on a parent directory, for example. (I guess you should check /usr/bin/php as well, but I assume that's sane)

You can also try running the command in a minimal environment:

# su -s /bin/sh -u cronuser
$ env - /bin/sh
$ /usr/bin/php -C /etc /path/to/process.php

to see if that works.

derobert
  • 109,670
  • We don't have a mailserver available to that server at the moment, which is why I'd set MAIL="" and was redirecting stdout and stderr. Will removing the MAIL line mean they go to my local mailbox without the lack of an SMTP host being a problem? The lines you give for testing permissions are roughly how I created the two .log files, fwiw. Thank you, though; I'll try all of that when I get to the office in the morning. – Owen Blacker Feb 07 '12 at 20:33
  • 1
    Hi @OwenBlacker. cron does not need a mailserver to send e-mails. You have just to loggon as cronuser or root and run mail without parameters. Hope this may help. Let us know... If /bin/ls -> /bin/bash, you may not need SHELL=/bin/bash. You may also replace > by >> for file redirection (eg. in > /path/to/test.txt) because of set -C. Very good answer => +1 – oHo Feb 07 '12 at 21:28
  • Awesome; I'll check that out in the morning, then. Thank you both. – Owen Blacker Feb 07 '12 at 21:39
  • Ok, so I've tested it in the minimal environment (with su -s /bin/sh cronuser and so on, as in this answer) and it runs ok. It still doesn't run from inside cron, though, even after removing the MAIL="" line. Frustratingly, it didn't generate any email either. There's no file at /var/spool/mail/cronuser, so I tried changing the MAIL line to MAILTO="blackero@localhost" but that doesn't cause it to run (or send me email) either. I'm still at a loss... – Owen Blacker Feb 08 '12 at 12:05
  • I've found the problem. And I feel stupid: see below – Owen Blacker Feb 10 '12 at 16:27
1

is crond running?

Try one of these commands:

pidof crond
pgrep -l crond
ps caxf | grep -6 crond --color

output of last command:

11881 ? S 0:00 \_ httpd 
11882 ? S 0:00 \_ httpd 
11883 ? S 0:00 \_ httpd 
11884 ? S 0:00 \_ httpd 
11885 ? S 0:00 \_ httpd 
11886 ? S 0:00 \_ httpd 
2098 ? Ss 0:01 crond             #this 'crond' is in red
2125 ? Ss 0:00 sudoscriptd 
2127 ? Ss 0:00 \_ sudoscriptd 
2136 tty2 Ss+ 0:00 mingetty 
2137 tty3 Ss+ 0:00 mingetty 
2138 tty4 Ss+ 0:00 mingetty 
2139 tty5 Ss+ 0:00 mingetty

What is the crond configuration?

Check your /etc/rc.d/init.d or /etc/init.d or whatever start-up file.

The crond configuration can list the denied or/and allowed users.
Is your user denied? Check these files:

   /etc/cron.allow
   /etc/cron.deny

If both files are absent, only root is allowed.
If cron.allow is absent and cron.denyis empty, then all users are allowed by default.

The file /etc/crontab must be writeable for root only:

$ ls -l /etc/crontab
-rw-r--r-- 1 root root 255 Jul 15  2006 /etc/crontab

What does crond say?

The natural way to receive information from crond is local mail. crond usually uses sendmail. If sendmail is not available, it is possible to give another mail command (CRONDARGS="-mmail").

But at this stage, the best is to check directly the crond logs (ll /var/log/cron*).

Restart crond

The issue may be fixed while restating crond...

If the issue is still there, then before another restart let's run it without init.d or service, and try other options:

sudo crond -p -x sch

And check again crond log files...

oHo
  • 1,258
  • 1
  • 12
  • 22
0

I've found the problem. The -C command line switch I'm sending to php, which should have been -c. I've no idea why cron wasn't reporting that to me in any manner, let alone a useful manner (or how I somehow managed to get it into the crontab with a capital C but test it on the CLI with a lowercase), but running it yet again in the CLI with a colleague here acting as my monkey and suddenly it was obvious.

Now how stupid do I feel?

Well, at least it's resolved now and cron is happily running my damn script. Thank you everyone for all your help.

  • You didn't get an error because php doesn't bother to report one. Nice :-( – derobert Feb 10 '12 at 17:51
  • Well there was an error somewhere eventually, but it was /bin/sh: /usr/bin/php /tmp/helloworld.php: No such file or directory, which is hardly helpful. At least I got the damn thing sorted :) – Owen Blacker Feb 10 '12 at 18:15