I want to run only one proccess at a time. So I need to check. I found there was suggestions to use exec()
so I made test functions - one which sleeps 1 minute and one which tests if process is running.
public function test($a='', $b='') {
exec("ps ax | grep 'php -q /var/www/glab/index.php ajax/test2'", $pids);
if (count($pids) > 2) {
$exists = true;
echo 'exists' . count($pids);
print_r($pids);
}
}
And I get result:
exists3Array
(
[0] => 30680 pts/8 S+ 0:00 php -q /var/www/glab/index.php ajax/test2
[1] => 30684 ? S 0:00 sh -c ps ax | grep 'php -q /var/www/glab/index.php ajax/test2'
[2] => 30686 ? S 0:00 grep php -q /var/www/glab/index.php ajax/test2
)
I did not expect 3 processes but I see its ok. Can I be sure that my function is working ok - detecting running when there is > 2, am I not missing something? For example maybe if some user will run some program on linux maybe this will not work anymore?
Or can you sugesst some check which matches only the one process, without sh and grep? I mean exact string. I was trying but cannot make it work to match only one which I am searching.
Edit:
googled bit more and found more examples, adjusted and have this:
exec ('ps -efa | grep "php -q /var/www/glab/index.php ajax/test2" |grep -v "grep " | awk "{print $10 $NF}"', $pids);
print_r($pids);
When process runs:
Array
(
[0] => darius 2046 12877 5 09:23 pts/8 00:00:00 php -q /var/www/glab/index.php ajax/test2
)
It matches now 1 processs. Could you check if this is ok, am I not missing something?
Related
What i want to achieve
I want to execute some script it it's process in not started on the server. so for that i am preparing the command in shell script and executing it in single line.
Command with php variable
$cmd = "if [[ `ps auxww | grep -v grep | grep ".$process_file." | grep '".$find."'` == '' ]] ; then ".$cmd2." fi";
echo $cmd."\n";
Executed command, once variables are replaced (what will actually run on bash):
if [[ `ps auxww | grep -v grep | grep /home/new_jig.php | grep 'test_51 1714052'` == '' ]] ; then php /home/new_jig.php test_51 1714052 & fi;
executing command
exec($cmd,$out,$res);
Please note that, I have also split the problem in to two statement and execute those. But it is time consuming. It is causing problems when I have more than 2000 in list, and the command is executed for all. This takes about 1 or more than 1 minute to reach to the last number.
I want to achieve this within 10 seconds. Please help me to reach optimum output.
Thanks
Jignesh
somehow I am able to make it execute with the following command
$process_file = phpfile which executing some functionality
$cmd2 = " php ".$process_file." 1212 >/dev/null 2>/dev/null & ";
$cmd11 ="if ps -auxw | grep -v grep | grep '".$process_file."' | grep '".$find."' &> /dev/null ; then echo 1;".$cmd2."; fi";
shell_exec($cmd11." >/dev/null 2>/dev/null &");
Before this: for 1100 request the process was taking about 60+ seconds
After this: it is getting completed between 20 to 30 seconds
I have a php script that runs via a cron job.
I have an exec command in the script like so:
exec("ps -u bob -o user:20,%cpu,cmd | awk 'NR>1' | grep vlc | tr -s ' ' | cut -d ' ' -f 2",$cpu,$return)
This gets me the cpu form a process run by a specific user, if the process exists. When run via the command line I get say 21 or nothing at all depending on if the process is running or not. However, when running vai the PHP script, I get the following:
[0] => bob 0.0 /bin/sh -c php /home/bob/restart.php bob
[1] => bob 0.0 php /home/bob/restartStream.php bob
[2] => bob 0.0 sh -c ps -u bob -o user:20,%cpu,cmd | awk NR
It seems to be returning all the recent commands executed as opposed to the result of the command executed.
I have seen some posts which show the use of 2>&1 which I believe redirects the stdin and stdout or soemthing similar. However I have tried this in my command like so:
ps -u bob -o user:20,%cpu,cmd | awk 'NR>1' | grep vlc | tr -s ' ' | cut -d ' ' -f 2 2>&1
But it does not seem to make a difference. Can any give me any pointers as to why this is occurring and what can possibly be done to resolve this.
You need to clear out $cpu before you call exec. It appends the new output to the end of the array, it doesn't overwrite it.
You can also get rid of grep, tr, and cut and do all the processing of the output in awk
$cpu = array();
exec("ps -u bob -o user:20,%cpu,cmd | awk 'NR>1 && /vlc/ && !/awk/ {print $2}'",$cpu,$return);
The !/awk/ keeps it from matching the awk line, since that contains vlc.
When I run ps ax command in console via putty I get:
1053 ?? Ss 0:45.47 /usr/local/sbin/nrpe2 -d -c /usr/local/etc/nrpe.cfg
1085 ?? Is 0:00.03 /bin/sh /usr/local/bin/mysqld_safe --defaults-extra-file=/var/db/mysql/my.cnf --user=mysql --datadir=/var/db/mysql --pid-file=/var/db/mysql/MYNAME.pid
But when I run this command via php:
exec('ps ax', $o);
print_r($o);
I get the same, but cutted!
[27] => 1053 ?? Ss 0:45.48 /usr/local/sbin/nrpe2 -d -c /usr/local/etc/nrpe.cfg
[28] => 1085 ?? Is 0:00.03 /bin/sh /usr/local/bin/mysqld_safe --defaults-extra-f
Why are all characters from position >=79 truncated?
Here's the technique we used on our script:
exec("export COLUMNS=1000; ps ax | grep $parameter", $results);
Here's what COLUMNS means:
COLUMNS
Used by the select builtin command to determine the terminal width when
printing selection lists. Automatically set upon receipt of a SIGWINCH.
I would like to have a shell scipt that runs infinitely and keeps checking status of a php script (say my.php) and restarts it if the script has terminated somehow. I have the idea to go for -
ps -aux | grep "my.php"
and then use the result of this to check the status and do accordingly. Thanks in advance.
You can simply say:
ps -aux | grep -q "my.php" || php -f my.php
The way it works is that grep -q will not output anything but will return an "OK" exit code if it found something. when it returns a "NOT OK" exit code, the part after the || ("or") gets executed (because of boolean short-circuit evaluation - look it up).
You also need to make sure that:
you run the new script in the background and detach it from your console so that your script can keep monitoring
when you run ps | grep sometimes ps also lists your grep and then the grep "greps itself", so you have to filter that out.
It should look something like this:
while true
ps -aux | grep -v grep | grep -q "my.php" || ( nohup php -f "my.php" & )
sleep 1
done
or some-such..
Another approach is, start your php-program in a loop:
for ((;;))
do
my.php
done
With Linux ps, you could use
ps -C "my.php"
instead of grep, to identify my.php. Grep commands often find themselves. Maybe your ps has a similar switch?
If you DO really feel the need to grep the output of ps, beware of your grep finding itself.
[ghoti#pc ~]$ sleep 60 &
[1] 66677
[ghoti#pc ~]$ ps aux | grep sleep
ghoti 66677 0.0 0.0 3928 784 11 S 4:11PM 0:00.00 sleep 60
ghoti 66681 0.0 0.0 16440 1348 11 S+ 4:12PM 0:00.00 grep sleep
[ghoti#pc ~]$
There's an easy way to avoid this. Just make part of your grep into a more complex regular expression.
[ghoti#pc ~]$ sleep 60 &
[2] 66717
[ghoti#pc ~]$ ps aux | grep '[s]leep'
ghoti 66677 0.0 0.0 3928 784 11 S 4:11PM 0:00.00 sleep 60
ghoti 66717 0.0 0.0 3928 784 11 S 4:13PM 0:00.00 sleep 60
[ghoti#pc ~]$
On the other hand, if you just want to make sure that your PHP script always runs, you can wrap it in something that re-runs it when it dies:
while true; do
php /path/to/my.php
done
If you want this to run at startup, you can edit your crontab on the server, and use a #reboot tag, assuming you're using "Vixie" cron (common on Linux and BSD):
#reboot /path/to/wrapperscript
You can man crontab and man 5 crontab for more details on how to use cron and the #reboot tag.
I have again another trouble with using exec in php
my os is suse linux and I am using php 5.1.2
Somehow my output is being trimmed when i use exec()
in linux
~ -> ps -ef | grep java
root 3548 1 0 Aug05 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java -server -Djava.awt.headless=true -Xms512m -Xmx512m -XX:NewSize=224m -XX:MaxNewSize=256m -XX:SurvivorRatio=8 -XX:+UseParallelGC -jar /jfe-server.jar start
psinl 14811 1 0 09:12 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java -server -Djava.awt.headless=true -Xms512m -Xmx512m -XX:NewSize=224m -XX:MaxNewSize=256m -XX:SurvivorRatio=8 -XX:+UseParallelGC -jar jfe-server.jar start
psinl 18164 18080 0 16:20 pts/1 00:00:00 grep java
but when output to web via
<div>Checking whether JFEServer has been started</div>
<div><pre><?php exec('ps -ef | grep java',$output,$result);
print_r($output); ?></pre>
</div>
</br>
And my output on the web
Checking whether JFEServer has been started
Array
(
[0] => root 3548 1 0 Aug05 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java
[1] => psinl 14811 1 0 09:13 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java
[2] => psinl 18069 14271 0 16:20 ? 00:00:00 sh -c ps -ef | grep java
[3] => psinl 18071 18069 0 16:20 ? 00:00:00 grep java
)
Why is that php has automatically trimmed off my output even I didnt want it to?
This is because PHP just doesn't can't allocate a large enough buffer for you to use with exec. Your best bet is to add a step in between: pipe the output to a temporary file in your exec() call
example: exec('ps -ef | grep java > /tmp/mytmpfilename.txt')
...then dump that out to the screen with a call to file_get_contents()
example: var_dump(file_get_contents('/tmp/mytmpfilename.txt'));
edit: Alternatively, you can use file() if there is a LOT data to output, like several thousand lines worth.
You could use passthru, which passes the output of a command directly to the clients browser.
<div>Checking whether JFEServer has been started</div>
<div><pre><?php passthru( 'ps -ef | grep java', $result ); ?></pre></div>
<br />
If that doesn't help, you should look into the documentation of ps, if it tests the standard output terminal type (e.g. file/pipe/terminal). If it does so, it could be trimming it to some default width if it can't determine the actual terminal width. On my debian based server it does. The correct command on my machine is:
<div>Checking whether JFEServer has been started</div>
<div><pre><?php passthru( 'ps -efww | grep java', $result ); ?></pre></div>
<br />
I had to add the -w flag to double my ps output on Centos 6.2. Of course, this only is necessary sometimes, specifically in a session run from a script.
In a TTY session, ps will not trim the output, but in other circumstances (depending on the TERM variable, it will. You can also explicitly set it to unlimited by adding -ww.
ps man pages were the key for me on this one.
php did not trim you output, the browser did. check the original output by Right click -> View Page Source on browser.