php exec output being trimmed - php

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.

Related

How to let php artisan serve run as a background server to work like Apache?

I setup a Laravel app on a VPS. It's for demonstration purposes only.
I would ssh login to the VPS using PuTTY and type:
php artisan serve --host x.x.x.x
Everything works fine. However, when I close the PuTTY connection, the server shuts down.
Is it possible to let the artisan server run in the background just like Apache?
You can run any shell command in the background by adding & to the end. If you want it to continue to run after you've disconnected, then run it with nohup
nohup php artisan serve &
To kill it later, you'll be given a process ID, but don't be fooled because this kicks off other processes that will persist even when killed. To get the actual server PID, you can find it by filtering ps output with grep
ps -ef | grep "$PWD/server.php"
Should give you some output like this:
jeff 23978 23977 0 16:50 pts/4 00:00:00 /usr/bin/php7.0 -S 127.0.0.1:8000 /path/to/laravel-project/server.php
jeff 24059 18581 0 16:51 pts/4 00:00:00 grep --color=auto /path/to/laravel-project/server.php
The first number after your username is the PID you want to kill.
kill 23978
Don't do this for a production site, but a quick demo might be ok.
Probably the quickest way to do this, at least on a temporary level, is to use screen - You can run it in a screen session and then Ctrl-a then d in Putty/shell to minimize it. It will continue running after your session closes.
You can resume and kill or restart later.
Adding on to Jeff's answer, you might want to doublecheck if the command stopped.
In my case something like this happened:
create
nohup php artisan serve &
ps -ef | grep "$PWD/server.php"
output example:
jeff 23978 23977 0 16:50 pts/4 00:00:00 /usr/bin/php7.0 -S 127.0.0.1:8000 /path/to/laravel-project/server.php
jeff 24059 18581 0 16:51 pts/4 00:00:00 grep --color=auto /path/to/laravel-project/server.php
kill and double check
kill 23978
ps -ef | grep "$PWD/server.php"
output example:
jeff 23964 23977 0 16:50 pts/4 00:00:00 /usr/bin/php7.0 -S 127.0.0.1:8001 /path/to/laravel-project/server.php
jeff 24059 18581 0 16:51 pts/4 00:00:00 grep --color=auto /path/to/laravel-project/server.php
issue
The php artisan serve had not actually stopped but just changed ports and ID!
id: 23978 => 23964 port: 127.0.0.1:8000 => 127.0.0.1:8001
solution
run the kill comment with the ID to the right side first, which you can also get with this command:
ps aux | grep artisan
so in order it would be:
kill 23977
ps -ef | grep "$PWD/server.php"
output example:
jeff 23964 1 0 16:50 pts/4 00:00:00 /usr/bin/php7.0 -S 127.0.0.1:8001 /path/to/laravel-project/server.php
jeff 24059 18581 0 16:51 pts/4 00:00:00 grep --color=auto /path/to/laravel-project/server.php
If the number changes to 1 it died. Then:
kill 23964
ps -ef | grep "$PWD/server.php"
output example:
jeff 24059 18581 0 16:51 pts/4 00:00:00 grep --color=auto /path/to/laravel-project/server.php
And the php artisan serve should stop.

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.
~

php linux regex how to match if cron process is running?

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?

Screen output to PHP

I have a PHP file with shell commands running through a screen, the commands run fine but I was wondering if there was a way to get this to output to PHP without writing to another file and reading it on PHP's end.
PHP - trace() is just a fancy print_r()
$cmd = 'ls -h /';
trace(shell_exec('screen -S output -p 0 -X stuff "`echo '.$cmd.'\'\r\n\'`"'));
Web output
NULL
Screen output
www-data#:/home/ubuntu$ ls -h /
bin build etc initrd.img lib media opt root selinux sys usr vmlinuz
boot dev home initrd.img.old lost+found mnt proc sbin srv tmp var vmlinuz.old
Any suggestions?
--Edit--
Certain commands aren't outputting directly, one of the reasons I'm using screen
PHP
$cmd = 's3ls';
trace(shell_exec('screen -S output -p 0 -X stuff "`echo '.$cmd.'\'\r\n\'`"'));
trace(shell_exec($cmd));
Web output
trace:NULL
trace:NULL
Screen
www-data#:/home/ubuntu$ s3ls
+---------------+--------------------------+
| Name | CreationDate |
+---------------+--------------------------+
| bucket | 2012-05-31T13:08:51.000Z |
| bucket | 2012-01-17T16:51:58.000Z |
| bucket | 2012-03-31T11:19:54.000Z |
+---------------+--------------------------+
void passthru ( string $command [, int &$return_var ] )
The passthru() function is similar to the exec() function in that it
executes a command. This function should be used in place of exec() or
system() when the output from the Unix command is binary data which
needs to be passed directly back to the browser. A common use for this
is to execute something like the pbmplus utilities that can output an
image stream directly. By setting the Content-type to image/gif and
then calling a pbmplus program to output a gif, you can create PHP
scripts that output images directly.
Though apparently it may be a bit flaky.

shell script to check status of another script and restart it

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.

Categories