Execute background system command and capture output in a array using PHP - php

I'm trying to ping a bunch of IPs using PHP/HTML.
<?php
$ip=array("192.10.1.1","192.10.1.2","192.10.1.3","192.10.1.4","192.10.1.5")
$list=count($ip);
$instruction = "";
for ($x=0; $x<$list; $x++)
{
if ($x > 0)
{
$send2_bg =" & ";
}
else
{
$send2_bg = "";
}
$instruction = $instruction.$send2_bg."ping -c 2 -w 1 ". $ip[$x]." | grep -i received | awk '{print $4}'" ;
}
echo $instruction;
$result =exec($instruction);
?>
Expected output array
1 1 0 0 2
But I'm failing to get the output, The instruction is constructed perfectly but after exec(), the output is not as I expect.

exec() just returns the last line of the output
shell_exec() returns all output

Try capturing the output like this:
exec($command, $host, $output);
print_r($output);

The problem is that you are echoing the instruction var see that link - PHP manual
Please reffer to the parameter output and echo that one instead the instruction var.

Related

Php executing a bash script with at command

Hello I'am trying to execute a shell command in my php script but it is not working.
My php script :
//I save the Order
$holdedOrder->save();
$id = $holdedOrder->id;
$old_path = getcwd();
chdir(__DIR__.'/../');
$scriptFile = 'anacron_job_unhold_order.sh';
$bool = file_exists($scriptFile);
//$bool is true !
//this command works in shell but not in here do not know why
$s = shell_exec("echo \"/usr/bin/bash $scriptFile $id\" | /usr/bin/at now +$when");
chdir($old_path);
return [$s,$bool];
$when has a valid value 4 hours or 4 days ...
The command will be :
echo bash anacron_job_unhold_order.sh 29 | at now +1 minutes
the output is null. Trying it with exec() is returning 127 code
Edit :
I removed www-data from /etc/at.deny and still the same problem
The command shell_exec("echo \"/usr/bin/bash $scriptFile $id\" | /usr/bin/at now +$when"); is probably causing the issue, you should take a closer look on how at works.
The command should be something like
at [options] [job...]
To give a job to at from the command instead of STDIN, use heredoc syntax
at now + 1 minute <<< 'touch /tmp/test'
So the PHP code should be something like;
$s = shell_exec("/usr/bin/at now + {$when} <<< '/usr/bin/bash {$scriptFile} {$id}'");
exec($s, $output, $return_var);

Passing URL parameters from php script to bash

I'm trying to pass parameters from an URL (PHP script) to a Bash using a case control statement. The Bash script itself is working correctly, if run from the Linux machine, but calling via the URL returns and empty white page.
The bash script
case $1 in
allBG)
echo "Prilagane na status 1 - All BG";
cp /root/copyjob/status/xml/status1_allBG/tvip_provision.xml >/var/www/html/prov.mac/$2/tvip_provision.xml;
;;
allEU)
echo "Prilagane na status 2 - All EU za"
cp /root/copyjob/status/xml/status2_allEU/tvip_provision.xml >/var/www/html/prov.mac/$2/tvip_provision.xml
;;
eurotv)
echo "Prilagane na status 3 - eurotv";
cp /root/copyjob/status/xml/status3_eurotv/tvip_provison.xml >/var/www/html/prov.mac/$2/tvip_provision.xml;
;;
gotv)
echo "Prilagane na status 4 - gotv";
cp /root/copyjob/status/xml/status4_gotv/tvip_provision.xml >/var/www/html/prov.mac/$2/tvip_provision.xml;
;;
bixi)
echo "Prilagane na status 5 - bixi";
cp /root/copyjob/status/xml/status5_allbg/tvip_provision.xml >/var/www/html/prov.mac/$2/tvip_provision.xml;
esac
The php script
$status = $_GET['status'];
$mac = $_GET['mac'];
echo exec('/root/copyjob/status/status.sh $status $mac');
You need to use double quotes, if you want the PHP to be interpreted or end your string and concat the variables to your string.
So its either:
echo exec("/root/copyjob/status/status.sh $status $mac");
or:
echo exec('/root/copyjob/status/status.sh ' . $status . ' ' . $mac);
Edit: Sorry, missed the echo. If you wanna output something from it you got to use the 2nd and 3rd parameter of exec:
<?php
$status = $_GET['status'];
$mac = $_GET['mac'];
$output = array();
$return_var = null;
exec("/root/copyjob/status/status.sh $status $mac", $output, $return_var);
var_dump($output);
var_dump($return_var);

passing value from php to python

I know this has been asked and answered numerous times on this site but I'm still having some trouble.
from bash:
sudo python test1.py blue
test1.py
import sys
who = sys.argv[1]
print sys.argv[1]
print who
outputs:
blue
blue
from PHP
$ledcolor = "0,255,0";
$result = exec("sudo python test1.py blue");
$result = exec("sudo python test1.py" . $ledcolor);
$result = exec('sudo python test1.py' . $ledcolor);
$result = exec('sudo python test1.py blue');
all result in no output from python
I have also tried shell_exec in PHP with same (no) results.
$result = exec("sudo python test1.py blue" . $ledcolor);
echo "\n";
print $result;
PHP Output = blue0,255,0
what am I doing wrong?
In php, the exec function passes its full output via a parameter passed by reference :
$out = '';
$cmd = exec('/bin/somecommand some parameters', $out);
echo $out;
$cmd holds the return status of the exec call, not the output.
Ref : http://php.net/manual/en/function.exec.php
You can use shell_exec instead of exec, or ` `.
$result = `sudo python test1.py blue`;

php - shell_exec , exec, etc.. can not get output like in terminal. even with 2>&1

First let's run the command via terminal:
$ echo 1; /etc/init.d/apache3 restart; echo 2;
result.. ( apache3 on purpose to see an error )
1
bash: /etc/init.d/apache3: No such file or directory
2
awsome.
now let's run this via php..
<?php
$command = "echo 1; /etc/init.d/apache3 restart; echo 2; 2>&1";
$response = shell_exec("$command");
echo $response;
?>
all I see on the browser is: 1 2
I tried all sorts of things. replaced the semi colons with "&&"..
tried all the php stuff such as..
passthru()
exec()
system()
popen()
i tried it all pretty much. been hours.. can not get it to show me the same stuff i see via terminal.
You have to use 2>&1 after the restart command
Your command :
$command = "echo 1; /etc/init.d/apache3 restart; echo 2; 2>&1";
yours has "2>&1" at the end which has no use.
Also you will add to 2>&1 after each command in case others uses STDERR
$command = "echo 1; /etc/init.d/apache3 restart 2>&1; echo 2 ";
Consider using exec. The basis function only returns the first line of the output:
$response = exec("$command"); // just the first line
But use the additional parameters to capture both the output (as an array) and the return value
$retval = NULL;
$output = NULL;
$response = shell_exec("$command", $output, $retval); // last two params are passed by reference and modified by the command
Also, as user993553 posted, the output captured by these cli functions in PHP will usually just return stdout and not stderr. You can append " 2>&1" to any given command (note the space before the 2) in order to route stderr into the output.
That said, your function becomes:
$command = "echo 1; /etc/init.d/apache3 restart 2>&1; echo 2;";
$retval = NULL;
$output = NULL;
$response = exec($command, $output, $retval);
var_dump($output);
and the output:
array(3) {
[0] =>
string(1) "1"
[1] =>
string(37) "sh: 1: /etc/init.d/apache3: not found"
[2] =>
string(1) "2"
}
EDIT: you can also check $retval for an error condition. If it's not empty or zero, then signifies an error.
From the manual of shell_exec:
ALSO, note that shell_exec() does not grab STDERR, so use "2>&1" to
redirect it to STDOUT and catch it.

php stripping a particular result from an output

I am using php to grab a shell output that lists all the meetme channels for me. I just want to grab the Conf Num that has 0001 from the bottom up. In my example below, I would like to assign variable: $confnum="32";
Here is my code so far:
$output = shell_exec("asterisk -rx 'meetme list'");
echo $output;
Please help me take the results from $output.
Here's what you'll get when executing the meet.php file
[root#C1033-TF agi-bin]# php meet.php
Conf Num Parties Marked Activity Creation Locked
67 0001 N/A 00:00:16 Dynamic No
28 0001 N/A 00:00:19 Dynamic No
65 0001 N/A 00:01:14 Dynamic No
42 0001 N/A 00:01:18 Dynamic No
32 0001 N/A 00:04:18 Dynamic No
* Total number of MeetMe users: 5
Please keep in mind that sometime there will be more than just 0001 Parties in the Conf Num. In the example above, I just want to grab the line:
32 0001 N/A 00:04:18 Dynamic No
This is the last line that has 0001 therefore assign $confnum="32"; to it.
Any kind of help I can get on this is greatly appreciated.
You can use exec instead of shell_exec and iterate through the output lines:
<?php
$output = array();
exec("asterisk -rx 'meetme list'", $output);
foreach ($output as $line) {
if (preg_match('/^32\s/', $line)) { //Check line starts with 32
echo $line;
}
}
Edit:
<?php
$output = array();
exec("asterisk -rx 'meetme list'", $output);
$lines = sizeof($output);
for ($i = $lines -1; $i >=0 ; $i--) {
if (preg_match('/^(\d+)\s+0001\s/', $output[$i], $matches)) { //Check line contains 0001
$firstNumber = $matches[1];
echo $firstNumber;
break;
}
}
Okay, assuming Linux, you can do this purely in shell:
filter last line: grep -v 'Total number of MeetMe isers'
filter first line: grep -v 'Conf Num'
and print only one Conf Num: awk 'BEGIN{ result=""; } {if( $2 == "0001"){result=$1;}} END {print result;}'
So the whole code:
$output = shell_exec("asterisk -rx 'meetme list' | grep -v 'Total number of MeetMe isers' | grep -v 'Conf Num' | awk 'BEGIN{ result=\"\"; } {if( \$2 == \"0001\"){result=$1;}} END {print result;}'");
// $output should contain your data :)
Or use preg_match_all():
$output = shell_exec("asterisk -rx 'meetme list'");
$matches = array();
$result = null;
preg_match_all('~^\s*(\\d+)\\s+0001~', $output, $matches, PREG_SET_ORDER);
foreach( $matches as $match ){
$result = $match[1];
}
In reaction to comment:
You should study regular expression syntax and meaning of \d and +. \d+ will match 0, 01 or 00000000000000000000000000000000 :).

Categories