Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running php from cron did not run as CLI

Tags:

php

cron

I noticed this problem after a php script ran from cron started to timeout but it was not an issue when it was ran manually from command line. (PHP has max_execution_time is 0 for CLI by default)

So I tried to run a simple cron such:

50 8 * * * php -q /tmp/phpinfo.php > /tmp/phpinfo

The script would just call phpinfo().

Surprisingly it wrote out phpinfo in html format, which suggested that it was not run as CLI. And max_execution_time was 30 in the output.

Running the script manually from command line such

php -q /tmp/phpinfo.php | less

wrote out the php info in text format and max_execution_time was 0 in the output.

I know there must be a configuration issue somewhere, but I just could not find where the problem is. This is happening on a production server, which I have a complete control of. Running the same script from cron on my development machine worked fine.

Here is the summary of the difference

function             | CLI                     | cron                   |
php_sapi_name        | cli                     | cgi-fcgi               |
php_ini_loaded_file  | /usr/local/lib/php.ini  | /usr/local/lib/php.ini | 
like image 296
Adrian Gunawan Avatar asked Nov 11 '13 22:11

Adrian Gunawan


1 Answers

I suspect your problem lies in a missing environment variable, specifically the all-important $PATH. When you run this:

php -q /tmp/phpinfo.php

the system must work out what program you mean by php. It does this by looking, in order, through the directories in the current $PATH environment variable.

Executed from a normal shell, your environment is set up in such a way that it finds the CLI version of PHP, as you expect.

However, when cron executes a command, it does so without all the environment variables that your interactive shell would set up. Since there will probably be other executables called php on your system, for different "SAPIs", it may pick the "wrong" one - in your case, the cgi-fcgi executable, according to the output you report from php_sapi_name().

To fix this, first find the path to the correct php executable in a normal shell by typing this:

which php

This should give you a path like /usr/bin/php. You can go one further and check if this is actually a "symbolic link" pointing at a different filename:

ls -l $(which php)

(you'll see an arrow in the output if it is, like /usr/bin/php -> /usr/bin/php5-cli)

Then take this full path to the PHP executable and use that in your crontab entry, so it looks something like this:

50 8 * * * /usr/bin/php5-cli -q /tmp/phpinfo.php > /tmp/phpinfo
like image 165
IMSoP Avatar answered Oct 23 '22 10:10

IMSoP