6

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 | 
5
  • To confirm if it is actually in CLI mode, try echoing out php_sapi_name(). You could also check what php.ini is being included with php_ini_loaded_file() and php_ini_scanned_files. The most common cause of discrepancies of this sort is that you have some "environment variables" set for your normal shell which will not be set when cron runs. Commented Nov 11, 2013 at 22:15
  • No that is incorrect. This is from the phpinfo docu page "Note: phpinfo() outputs plain text instead of HTML when using the CLI mode." Commented Nov 11, 2013 at 22:28
  • Get rid of the -q flag. You don't need it, and it could even be the cause of this problem. Commented Nov 11, 2013 at 22:34
  • -q was not the problem. That is for a quiet mode and yes I've tried removing this. Commented Nov 11, 2013 at 22:37
  • I was interested to find out what the other differences might be between running cli and cgi-fcgi from shell. Here is a list from php.net: us.php.net/manual/en/features.commandline.differences.php Commented Aug 15, 2015 at 21:49

1 Answer 1

16

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
Sign up to request clarification or add additional context in comments.

4 Comments

That was exactly the problem. Thanks for your suggestion. I ended up adding the following on the top of cron so that I dont need to change the command. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
This works for me too, changed "php" to "/usr/local/bin/php", my output from "which php" and it's running as a CLI from cron now.
Great info, thanks that helped much! Although it didn't help in the end with my problem, why CRON PHP runs without proper mask S_IFCHR and instead it presents (STDIN) as S_IFIFO.
Man, you saved me !! Was trying to find a way to fix that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.