Checking PHP script running in process - php

ps ax | grep -i 'php complete.php'
<?php
exec("ps ax | grep -i 'php complete.php'", $pids);
if(!empty($pids)) {
die("already running");
}
I went to check my ps ax, but din't saw the complete.php , and I went check a folder which will output something if complete.php is running, but nothing output.
It giving me a false positive. how do I check if the script complete.php is currently running.
Reason is because I want it to run synchronously and I had a endless loop execute complete.php every 2 minutes acting like a cron job.

You'd only see the php process running. My approach for seeing a php process running is to alias the php binary and run it with that.
ln -s /usr/bin/php longrunningphp
longrunningphp /path/to/your/script
Then check with ps ax | grep longrunningphp

I had the same problem. When running in the console, you will get the result, but when the same command is used in the PHP, nothing would be returned. The problem lies somewhere in terminal width that is allowed for PHP. Simple solution would be to increase it. Example:
exec("export COLUMNS=1000; ps ax | grep -i 'php complete.php'", $pids);
COLUMNS
Used by the select command to determine the terminal width when printing
selection lists. Automatically set upon receipt of a SIGWINCH.

Related

PHP `exec()` doesn't work if run by a process initiated from Cron

I have a Beanstalk MQ where I put task to create APK, and a consumer named AppBuilder.php, which reads messages from Beanstalk MQ, and then exec the command which creates the App (android app).
The AppBuilder.php is run from the crontab. the process is
Crontab runs a health-check.sh shell script
health-check.sh runs AppBuilder.php in background
AppBuilder.php calls exec to create the process
Following is the relevant code snippet(s) from each file:
Root crontab is like so:
* * * * * /opt/cron/health-check/health-check.sh
health-check.sh is like this:
#!/bin/bash
PATH=$PATH:/sbin/
#HEALTH CHECK FOR AppBuilder Daemon
if (( $(ps -ef | grep "[A]ppBuilder" | wc -l) > 0 ))
then
echo "AppBuilder is Running"
else
echo "AppBuilder is Stopped, attempting to restart"
$PHP_CMD /opt/appbuilder/AppBuilder.php &
if pgrep "AppBuilder" > /dev/null
then
echo "AppBuilder is now Running"
else
echo "AppBuilder is still not Running"
fi
fi
AppBuilder.php has following exec command:
exec('sudo sh /var/www/cgi-bin/appbuilder/oneClickApk.sh &', $output, $resultCode);
If I run the AppBuilder.php directly, things work fine. However, from cron, it does not.
I've followed this SO Post, and modified the exec command to the following:
exec('/usr/bin/nohup /usr/bin/sudo /usr/bin/env TERM=xterm /bin/sh /var/www/cgi-bin/appbuilder/oneClickApk.sh &', $output, $resultCode);
However, still things fail. Any clues where this may be going wrong? I've spend a lot of time digging the forums, none helping. Please help!
EDIT 1:
The crontab runs, AppBuilder.php gets initialized, but after exec command, I could not see the oneClickApk.sh in process list
EDIT 2:
I changed the crontab from root to ec2-user, as suggested in comments: Still the process does not run.
Just following your first approach like below. But to fix the issue you have to do the following.
Check your cron-tab entry whether properly set or not.
In cron-tab provide full path to your executable
Check whether cron-tab user account has proper setting to execute sudo
Check whether cron-tab account has proper permission to execute your PHP application as well as your shell script. If not add the account into the proper group so that it can run both the PHP and shell script.
exec('sudo sh /var/www/cgi-bin/appbuilder/oneClickApk.sh &', $output, $resultCode);
Use above command its seems OK.
In you shell script put a wait command and check whether it is working fine or not. Just add only below two lines without any if condition first. If working then you need to check your if condition why they are not satisfying as per your requirement.
$PHP_CMD /opt/appbuilder/AppBuilder.php &
while (( $(ps -ef | grep "[h]ealth-check.sh" | wc -l) <= 0 ))
do
sleep 5
done
sleep 30

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)

shell_exec not returning the same result as sudoed command line

I'm developping a PHP-FPM driven module in which in upload videos, then transcode them into several HTML5 formats in the background with ffmpeg. This PHP-FPM script runs under a specific, non-root UID, called tv25.
There is a variant in which I record a webcam stream through a Streaming Server (Wowza), which runs under the root UID, and launches the conversion through Java-written module.
In order to know the status of the processes I make a GET request to a script which runs the following function :
function is_conversion_running($base_file_name) {
$command = "sudo ps aux | grep {$base_file_name} | grep -v grep | wc -l";
$lignes = shell_exec($command);
return (bool) $lignes;
}
When I call this function through AJAX, it works for the PHP-FPM variant (the UID is the same, returns true while the conversion is running), but not with the Wowza variant (return false everytime).
The strange thing is that if I run the command in a shell, with the non-root UID, it works like a charm, since the ps command as been allowed to be run by this UID.
The problem seems similar to the one in shell_exec returns empty string, but the solution listed there doesn't work for me.
My /etc/sudoers line is like this :
tv25 ALL = (root) NOPASSWD: /bin/ps
Really can't figure out what is the deal...
What does the command return: 0 or NULL? In the second case the command probably failed alltogether. You can check with the exec function whether you get a non-zero exit code. Make sure to prefix your command with /bin/sh -c in that case.
PS: Do you really need the sudo for running ps? Normally you get all processes even without sudo.
Well I found another way to sikve my problem : since I want to know if the process is still running, I delegated the command in a shell script :
#!/bin/bash
BASE_NAME=`basename $0`
LIGNES=$(/usr/bin/sudo /bin/ps aux | grep "$1" | grep -v grep | grep -v $BASE_NAME | wc -l)
[ $LIGNES -eq "0" ] && exit 1
exit 0
And then I call it with passthru. Its return value parameter is then converted to boolean, negated, and returned by the function.
~

How do I stop a script running in UNIX?

I ran a php script, let's use "mytestscript.php" for example.
It will run continuously for a few hours. How can I stop it from the Terminal (UNIX) command line?
Assuming it's running in the background, under your user id: use ps to find the command's PID. Then use kill [PID] to stop it. If kill by itself doesn't do the job, do kill -9 [PID].
If it's running in the foreground, Ctrl-C (Control C) should stop it.
Read the documentation on the ps command and familiarize yourself with its options. It's a very useful command.
You can try using ps -e | grep php to find all processes that have 'php' in their name. After that, you can do kill <PID>, replacing <PID> with the number the ps command gave you.
If you want an automated solution try this -
1.Create a new shell script - vi killer.sh
2.Add the following
#!/bin/bash
while true
do
sleep $1
ps -ef | grep mytestscript.php | grep -v grep | awk '{print $2}' | xargs kill -9
done
3.Grant executable permissions chmod +x killer.sh
4.Execute your script as nohup ./killer.sh <time to sleep before killing> &
5.Leave it and go to the beach!
You can always find the process id of the running process. "ps -ef | grep mytestscript.php". Look at the output and note down pid of the process. use kill pid to kill the process.

How to check if a php script is still running

I have a PHP script that listens on a queue. Theoretically, it's never supposed to die. Is there something to check if it's still running? Something like Ruby's God ( http://god.rubyforge.org/ ) for PHP?
God is language agnostic but it would be nice to have a solution that works on windows as well.
I had the same issue - wanting to check if a script is running. So I came up with this and I run it as a cron job. It grabs the running processes as an array and cycles though each line and checks for the file name. Seems to work fine. Replace #user# with your script user.
exec("ps -U #user# -u #user# u", $output, $result);
foreach ($output AS $line) if(strpos($line, "test.php")) echo "found";
In linux run ps as follows:
ps -C php -f
You could then do in a php script:
$output = shell_exec('ps -C php -f');
if (strpos($output, "php my_script.php")===false) {
shell_exec('php my_script.php > /dev/null 2>&1 &');
}
The above code lists all php processes running in full, then checks to see if "my_script.php" is in the list of running processes, if not it runs the process and does not wait for the process to terminate to carry on doing what it was doing.
Just append a second command after the script. When/if it stops, the second command is invoked. Eg.:
php daemon.php 2>&1 | mail -s "Daemon stopped" you#example.org
Edit:
Technically, this invokes the mailer right away, but only completes the command when the php script ends. Doing this captures the output of the php-script and includes in the mail body, which can be useful for debugging what caused the script to halt.
Simple bash script
#!/bin/bash
while [true]; do
if ! pidof -x script.php;
then
php script.php &
fi
done
Not for windows, but...
I've got a couple of long-running PHP scripts, that have a shell script wrapping it. You can optionally return a value from the script that will be checked in the shell-script to exit, restart immediately, or sleep for a few seconds -and then restart.
Here's a simple one that just keeps running the PHP script till it's manually stopped.
#!/bin/bash
clear
date
php -f cli-SCRIPT.php
echo "wait a little while ..."; sleep 10
exec $0
The "exec $0" restarts the script, without creating a sub-process that will have to unravel later (and take up resources in the meantime). This bash script wraps a mail-sender, so it's not a problem if it exits and pauses for a moment.
Here is what I did to combat a similar issue. This helps in the event anyone else has a parameterized php script that you want cron to execute frequently, but only want one execution to run at any time. Add this to the top of your php script, or create a common method.
$runningScripts = shell_exec('ps -ef |grep '.strtolower($parameter).' |grep '.dirname(__FILE__).' |grep '.basename(__FILE__).' |grep -v grep |wc -l');
if($runningScripts > 1){
die();
}
You can write in your crontab something like this:
0 3 * * * /usr/bin/php -f /home/test/test.php my_special_cron
Your test.php file should look like this:
<?php
php_sapi_name() == 'cli' || exit;
if($argv[1]) {
substr_count(shell_exec('ps -ax'), $argv[1]) < 3 || exit;
}
// your code here
That way you will have only one active instace of the cron job with my-special-cron as process key. So you can add more jobs within the same php file.
test.php system_send_emails sendEmails
test.php system_create_orders orderExport
Inspired from Justin Levene's answer and improved it as ps -C doesn't work in Mac, which I need in my case. So you can use this in a php script (maybe just before you need daemon alive), tested in both Mac OS X 10.11.4 & Ubuntu 14.04:
$daemonPath = "FULL_PATH_TO_DAEMON";
$runningPhpProcessesOfDaemon = (int) shell_exec("ps aux | grep -c '[p]hp ".$daemonPath."'");
if ($runningPhpProcessesOfDaemon === 0) {
shell_exec('php ' . $daemonPath . ' > /dev/null 2>&1 &');
}
Small but useful detail: Why grep -c '[p]hp ...' instead of grep -c 'php ...'?
Because while counting processes grep -c 'php ...' will be counted as a process that fits in our pattern. So using a regex for first letter of php makes our command different from pattern we search.
One possible solution is to have it listen on a port using the socket functions. You can check that the socket is still listening with a simple script. Even a monitoring service like pingdom could monitor its status. If it dies, the socket is no longer listening.
Plenty of solutions.. Good luck.
If you have your hands on the script, you can just ask him to set a time value every X times in db, and then let a cron job check if that value is up to date.
troelskn wrote:
Just append a second command after the script. When/if it stops, the second command is invoked. Eg.:
php daemon.php | mail -s "Daemon stopped" you#example.org
This will call mail each time a line is printed in daemon.php (which should be never, but still.)
Instead, use the double ampersand operator to separate the commands, i.e.
php daemon.php & mail -s "Daemon stopped" you#example.org
If you're having trouble checking for the PHP script directly, you can make a trivial wrapper and check for that. I'm not sufficiently familiar with Windows scripting to put how it's done here, but in Bash, it'd look like...
wrapper_for_test_php.sh
#!/bin/bash
php test.php
Then you'd just check for the wrapper like you'd check for any other bash script: pidof -x wrapper_for_test_php.sh
I have used cmder for windows and based on this script I came up with this one that I managed to deploy on linux later.
#!/bin/bash
clear
date
while true
do
php -f processEmails.php
echo "wait a little while for 5 secobds...";
sleep 5
done

Categories