views:

184

answers:

4

I have a PHP script that I need to run every minute. I have made sure that the script works from the command line, and I'm using absolute paths to avoid any environment issues:

/usr/bin/php -q /var/www/myapp/services/myservice.php

Manually running that as root from the command line works fine, as I can see from the log file that my script writes to. To be sure, the script has execute permissions as well.

However, when placing the same exact command in a cron:

* * * * * /usr/bin/php -q /var/www/myapp/services/myservice.php

It does not run or at least it appear so. I've tried redirecting the output to another log file too:

* * * * * /usr/bin/php -q /var/www/myapp/services/myservice.php >> /mylog.log 2>&1

Still nothing. I have no indication whatsoever of the script being ran. I guess it doesn't, but I have no idea what else to look for. I even restarted the cron daemon.

I know there are similar questions on StackOverflow, but none of the answers turned out to be a solution for me. This is literally driving me crazy, I will greatly appreciate any help.

A: 

you missed the running user section:

*      *       *       *       *       nobody  /usr/bin/php -q /var/www/myapp/services/myservice.php >> /mylog.log 2>&1
silent
Which cron needs that?
paxdiablo
/etc/crontab on my freebsd and ubuntu box told me.I don't know if you can run crontab without specifying the running user. But, what I always do is, set who should run the script.
silent
A: 

I found a solution for my issue:

http://serverfault.com/questions/97828/php-from-command-line-path-problems/97881#97881

It turns out I needed to cd (change directory) into the script dir and then call it. Surprising, since I'm using absolute paths, but it works. Thanks to those who have taken the time to respond.

Ferdy
+1  A: 

There are usually a significant number of things you need to do to move an executable from the command line to a cron job.

By default, cron jobs get a minimal environment which will almost certainly not have the full path (and a host of other environment variables) that your login sessions have. You may also not be in the same directory (as you have discovered).

What I tend to do is to execute:

env | sed 's/^/export /' >$HOME/cron.env

from a login session to get the full environment, then make sure that my cron jobs execute that script before attempting to do the real work. The resultant script may need a small amount of tidying up (quoting, removing transient environment variables like _ and PWD and so forth).

That way I can be sure that the login and cron environments are identical.

paxdiablo
You are right, I did have to "reset" a few path variables in the script itself.
Ferdy
A: 

This might be considered "bad practice" but it works for me.

Run it with curl

* * * * * curl -s http://www.domain.com/services/myservice.php
Yegor
Bad practice or not, I've never been able to find any other way to do it. Especially if you're trying to hit the DB and whatnot. Gotta have everything running for that. (See paxdiablo's answer.)
Jeff Rupert
I specifically did not want to use curl for two reasons: 1) it involves TCP/IP and web server overhead which is not needed for this script. 2) I have a htaccess protected development environment and I do not want to send the plain text password in the curl command. Please do check my own answer below, I have it working as a normal cron now :)
Ferdy