Running php from cron did not run as CLI - php

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 |

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

Related

PHP isn't executing ps command (possible permission issue?)

I have a small script I tested on the command line using php test.php.
test.php
<?php
exec('ps -acux | grep test', $testvar);
print_r($testvar);
?>
This works fine. I am able to run the script and get the desired result. However, when I add the code to a file being run by my PHP server, the result is empty.
My OS is FreeBSD. Looking at the man page for ps the only restriction I see is on the -a option. It states:
If the security.bsd.see_other_uids sysctl is set to zero, this option
is honored only if the UID of the user is 0.
My security.bsd.see_other_uids is set to 1.
$ sysctl security.bsd.see_other_uids
security.bsd.see_other_uids: 1
The only thing I can think of is that the command is being run by my user when I run it via the command line whereas when run by PHP, it's being run by www. I'm not seeing anything in the manual of ps that indicates www shouldn't be able to run the command.
As per the comments you need to redirect stderr to stdout. This is achieved by 2>&1 to the end of your command. So an example of the PHP exec() is as follows:
exec('ps -acux | grep test 2>&1', $testvar);
This allows you to see potential errors. In my case there was no error and likely a bug of some sorts. However this is useful in all cases where you execute a command. If any error were to occur you can retrieve it to see what is happening with your command.

How can I check if a program is running in the background using a cron, and start it if needed?

I have the task to run a daemon in the background on a production server. However, I do want to be sure that this daemon always runs. The daemon is PHP process.
I tried to approach this by checking if the daemon is running, and if not: start it. So I have a command like:
if [ $(ps ax | grep -c "akeneo:batch:job-queue-consumer-daemon") -lt 3 ]; then php /home/sibo/www/bin/console akeneo:batch:job-queue-consumer-daemon & fi
I first do an if with ps and grep -c to check if there are processes running with a given name, and if not: I start the command ending with an &, forcing it to start.
The above command works, if I execute it from the command line the process gets started and I can see that is is running when I execute a simple ps ax-command.
However, as soon as I try to do this using the crontab it doesn't get started:
* * * * * if [ $(ps ax | grep -c "akeneo:batch:job-queue-consumer-daemon") -lt 3 ]; then php /home/sibo/www/bin/console akeneo:batch:job-queue-consumer-daemon & fi
I also set the MAILTO-header in the crontab, but I'm not getting any e-mails as well.
Can anyone tell me what's wrong with my approach? And how I can get it started?
An easy and old-style one is to create a bash file where you basically check if the process is running, otherwise you start it.
Here the content of the bash file:
#!/bin/bash
if [ $(ps -efa | grep -v grep | grep job-queue-consumer-daemon -c) -gt 0 ] ;
then
echo "Process running ...";
else
php /home/sibo/www/bin/console akeneo:batch:job-queue-consumer-daemon
fi;
Then in the crontab file you run the bash file.
There are special services for such tasks. For example http://supervisord.org/
Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems.
And you can manage it via f.e https://github.com/supervisorphp/supervisor
A command working on command line and not working in CRON, this happened to me and here is what solved my problem.
Run echo $PATH in your terminal, copy entire output.
Then type crontab -e and at top of file, write this
PATH=WHATEVER_YOU_COPIED_FROM_LAST_COMMAND_OUTPUT
PS: (more suggestions)
I think you need to install apt-get install postfix on Ubuntu to be able to send emails.
You should also see CRON logs by
grep CRON /var/log/syslog
i would recommend you to use supervisord, it handles these kinds of issues with automatic restart on failed services, additionaly, you can try to set the akeneo commands as a service.
Otherwise, if you would like to do it using cronjobs, you may have an issue with the php binary, you need to setup the absolute path :
e.g : /usr/bin/php
I would also recommend if you use cronjob:
Check the logs of the cronjob for additional issues
grep CRON /var/log/syslog
Clean it up using a standalone bash script (don't forget to chmod +x)

Running backgrounded script from php exec / shell_exec call is now failing and re-spawning where before it used to work

There is a commonly discussed method of starting a background process in PHP using the exec or shell_exec functionality.
I have had success with this in the past with batch email sending, and sending data to APIs in the background.
In a PHP page that you would call by ajax, you do something like this:
echo 'process running';
shell_exec('/usr/bin/php -q path_to_background_script.php > /dev/null &' );
exit;
The background process normally runs as if called by the owner of the php user like a terminal process.
Recently however, under a FASTCGI system (ea-php56) I have found this method has stopped working.
Instead of one process beginning from one web-request to the calling page, I am getting the background script continually terminating and being re-spawned with a new process id. Interestingly, the only way to stop this continual re-spawning is to disable the line in the calling script that starts the process. The re-spawning stops immediately when you save the calling file without the call to the background script.
This tells me that it is actually the calling script (requested by the browser) which is actually being re-spawned.
This is what the re-spawning looks like from the root terminal. Notice the PID changes everytime I look:
[root#*** public_html]# ps -ef | grep php
*user* 725 1 7 23:53 ? 00:00:00 /opt/cpanel/ea-php56/root/usr/bin/php-cgi /home/*user*/public_html/background-script_exec.php
root 727 32411 0 23:53 pts/1 00:00:00 grep php
[root#dev public_html]# ps -ef | grep php
*user* 757 1 5 23:53 ? 00:00:00 /opt/cpanel/ea-php56/root/usr/bin/php-cgi /home/*user*/public_html/background-script_exec.php
root 759 32411 0 23:53 pts/1 00:00:00 grep php
[root#dev public_html]# ps -ef | grep php
*user* 781 1 12 23:54 ? 00:00:00 /opt/cpanel/ea-php56/root/usr/bin/php-cgi /home/*user*/public_html/background-script_exec.php
I have tried disabling "PHP-FPM service for cPanel Daemons". I have tried 'ignore_user_abort()'. fastcgi_finish_request() function is not available so could not try that. I have tried creating a shell script instead to call the background PHP script, which I call from the calling script - but this also does exactly the same thing.
Apart from disabling the ability to trigger background scripts from a PHP web-page, this new PHP FastCGI behaviour is creating an erratic re-spawning process that does not stop without intervention mentioned above. It has made shell_exec / exec functions unstable!
Problem seems similar to that reported here:
php exec/shell_exec/system/popen/proc_open runs calling script itself infinite number of times on linux
but, suggestion reported here does not help in this case.
This seems to solve the problem. Using the 'php5-cli' instead of 'php'
shell_exec('/usr/bin/php5-cli path_to_background_script.php > /dev/null &' );
I had early tried 'php-cli' and found it did not exist - I did not think to check to see that it was named differently!
If having similar problems, have a look for the php binaries:
>>ls /usr/bin/php*
>>/usr/bin/php /usr/bin/php5 /usr/bin/php5-cli /usr/bin/php-config /usr/bin/phpize
use the one which is for command line, and it should then run properly.
-note that this issue was specifically on a linux cpanel easy-apache fastcgi-php system running on Centos.

PHP to exec casperjs/phantomjs script

I'm having trouble using PHP to execute a casperjs script:
<?php
putenv("PHANTOMJS_EXECUTABLE=/usr/local/bin/phantomjs");
var_dump(exec("echo \$PATH"));
exec("/usr/local/bin/casperjs hello.js website.com 2>&1",$output);
var_dump($output);
Which results in the following output:
string(43) "/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:."
array(1) {
[0]=>
string(36) "env: node: No such file or directory"
}
The only stackoverflow posts I could find hinted that there's a problem with my paths, and that maybe the PHP user can't access what it needs.
I have also tried the following: sudo ln -s /usr/bin/nodejs /usr/bin/node
Does anyone know what I would need to do or change for this error to resolve?
Thanks
My guess is you have something, somewhere, that assumes node is installed.
First, are you running php from the commandline? I.e. as php test.php in a bash shell. If so, you can run the commands, below, as they are. If through a web server the environment can be different. I'd start with making a phpinfo(); script, and then run the troubleshooting commands through shell_exec() commands. But, as that is a pain, I'd get it working from the commandline first, and only mess around with this if the behaviour is different when run through a web server. (BTW, if you are running from a cron job, again, the environment can be slightly different. But only worry about this if it works from commandline but does not work from cron.)
Troubleshoot hello.js
The easy one. Make sure your script does not refer to node anywhere. Also remember you cannot use node modules. So look for require() commands that should not be there.
Troubleshoot your bash shell
Run printenv | grep -i node to see if anything is there. But when PHP runs a shell command, some other files get run too. So check what is in /etc/profile and ~/.bash_profile . Also check /etc/profile.d/, /etc/bashrc and ~/.bashrc. You're basically looking for anything that mentions node.
Troubleshoot phantomjs/casperjs
How did you install phantomjs and casperjs? Are the actual binaries under /usr/local/bin, or symlinks, or are they bash scripts to the . E.g. on my machine:
cd /usr/local/bin
ls -l casperjs phantomjs
gives:
lrwxrwxrwx 1 darren darren 36 Apr 29 2014 casperjs -> /usr/local/src/casperjs/bin/casperjs
lrwxrwxrwx 1 darren darren 57 Apr 29 2014 phantomjs -> /usr/local/src/phantomjs-1.9.7-linux-x86_64/bin/phantomjs
And then to check each file:
head /usr/local/src/casperjs/bin/casperjs
head /usr/local/src/phantomjs-1.9.7-linux-x86_64/bin/phantomjs
The first tells me casper is actually a python script #!/usr/bin/env python, while the second fills the screen with junk, telling me it is a binary executable.

php exec crontab not working

I trying on my local CentOS 5.3 server, when I try to execute below line in my php code from apache webserver
exec("crontab -l", $output, $arg);
The $arg reply 127 (command not found code)
Then I changed below code
exec("/usr/bin/crontab -l", $output, $arg);
The $arg reply 126 (Permission problem code)
Here is my current permission of
/usr/bin/crontab -rwsr-sr-x 1 root root 311288 Mar 15 2007 /usr/bin/crontab.
And there is no /etc/cron.allow and /etc/cron.deny file.
I already turned off Safe_mode in php. Any suggestion to solve this problem?
////////////////////////////////////////////////////////////////////////////////
I note that my problem is related to selinux.
It is working, when I disable selinux
echo 0 > /selinux/enforce
But I don't want to disable selinux, is there any option in selinux to allow crontab from apache?
Add /usr/bin to your shell env path
Add crontab to the same group like of the webserver
Try in php exec("echo $PATH") to see the path variable. You can also look for unsetenv and temporarly disable it
You can look in the php error log for a detailed description of the error but as you said you are familiar with Linux I can't teach you about user right management. A note to the env variable and the path variable it's not always sure the env variable get exported when you run a program. This is maybe the case with your problem. It means either the os is broken or you have to attach the env variable manually to your program. A workaround can be to look where the shell is looking for programs and symlink the program. In your error log it seems that crontab is in the folder /usr/bin. Also this seems not to be a programming question. Ask at server.stackexchange why crontab isn't found. For example my env looks like this:
LC_PAPER=de_DE
LC_ADDRESS=de_DE
LC_MONETARY=de_DE
AF_PIDDIR=/tmp/af-piddir
UPNP_ROOT=upnpav://
SHELL=/bin/sh
TERM=xterm
DISABLE_GATEWAY=1
GTK2_RC_FILES=/etc/hildon/theme/gtk-2.0/gtkrc
TMPDIR=/var/tmp
MMC_SWAP_LOCATION=/media/mmc1
LC_NUMERIC=de_DE
MMC_MOUNTPOINT=/media/mmc1
OLDPWD=/root
HILDON_FM_OBEX_ROOT=obex://
LAUNCHWRAPPER_NICE_KILL=/etc/osso-af-init/nice-kill-launch-wrapper.sh
INTERNAL_MMC_MOUNTPOINT=/home/user/MyDocs
OSSO_VERSION=RX-51_2009SE_20.2010.36-2_PR_MR0
USER=root
LS_COLORS=no=00:fi=00:di=00;36:ln=00;35:pi=40;33:so=01;35:bd=40;32;00:cd=40;32;00:or=01;05;37;41:mi=01;05;37;41:ex=00;33:.cmd=00;32:.exe=00;32:.com=00;32:.btm=00;32:.bat=00;32:.sh=00;32:.csh=00;32:.tar=00;31:.tgz=00;31:.arj=00;31:.taz=00;31:.lzh=00;31:.zip=00;31:.z=00;31:.Z=00;31:.gz=00;31:.bz2=00;31:.bz=00;31:.tz=00;31:.rpm=00;31:.cpio=00;31:.jpg=00;35:.gif=00;35:.bmp=00;35:.xbm=00;35:.xpm=00;35:.png=00;35:.tif=00;35:
LC_TELEPHONE=de_DE
SESSION_BUS_PID_FILE=/tmp/dbus_session_bus.pid.user
OSSO_PRODUCT_HARDWARE=RX-51
STATESAVEDIR=/tmp/osso-appl-states
LAUNCHWRAPPER_NICE_TRYRESTART=/etc/osso-af-init/nice-launch-wrapper-tryrestart.sh
OSSO_PRODUCT_FULL_NAME=Nokia N900
OSSO_PRODUCT_RELEASE_FULL_NAME=Maemo 5
OSSO_PRODUCT_RELEASE_NAME=Maemo 5
MYDOCSDIR=/home/user/MyDocs
PATH=/usr/bin/gnu:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
LC_MESSAGES=de_DE
OSSO_PRODUCT_SHORT_NAME=Nokia N900
SESSION_BUS_ADDRESS_FILE=/tmp/session_bus_address.user
LC_IDENTIFICATION=de_DE
PWD=/home/user/MyDocs
EDITOR=/usr/bin/nano -w -c
LANG=de_DE
ERR=0
LC_MEASUREMENT=de_DE
PS1=[\033[1;36m][[\033[0;36m]\u\h[\033[0;37m]:\w[\033[1;36m]][\033[m]$ [\033[0;37;00m]
ILLEGAL_FAT_CHARS=/:*?<>|
OSSO_PRODUCT_KEYBOARD=German
AF_DEFINES_SOURCED=1
SHLVL=1
HOME=/root
SDL_AUDIODRIVER=pulse
OSSO_SWAP=/home/user/MyDocs
OSSO_PRODUCT_RELEASE_VERSION=20.2010.36-2
LS_OPTIONS=--color
LAUNCHWRAPPER_TRYRESTART=/etc/osso-af-init/launch-wrapper-tryrestart.sh
OSSO_PRODUCT_NAME=N900
AF_INIT_DIR=/etc/osso-af-init
MMC_DEVICE_FILE=/dev/mmcblk0p1
LOGNAME=root
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-eCbOI2qrVP,guid=cd1dea104334a338a9007b9700000014
LAUNCHWRAPPER=/etc/osso-af-init/launch-wrapper.sh
OSSO_PRODUCT_WLAN_CHANNEL=fcc/us
MAX_FILENAME_LENGTH=255
DISPLAY=:0.0
LAUNCHWRAPPER_NICE=/etc/osso-af-init/nice-launch-wrapper.sh
LC_TIME=de_DE
INTERNAL_MMC_SWAP_LOCATION=/home/user/MyDocs
LC_NAME=de_DE
OSSO_PRODUCT_REGION=Germany
_=/usr/bin/gnu/env
Just type env in the prompt.

Categories