PHP shell_exec() - not printing dynamic ou

2019-07-14 22:41发布

****UPDATE****
# The issue was within the wanpipemon script and the way that it interacts 
# with ioctl basically unless you want to edit the source for wanpipemon 
# and recompile it, it will not work. I have tried -S with root among 
# others and unless I am within console it throws a not authorized error 
# in the ioctl function.

Ok I have a simple shell script that runs a command and outputs the FXO line voltages, normally you would have to get one line at a time this one combines them to one readable output. (irrelevant to this post but I thought someone might ask what this script does)

This is the shell script:

#!/bin/bash

LINE1=$(wanpipemon -i w1g1 -c astats -m 1 | grep -m1 VOLT | cut -d ":" -f 2-2)
LINE2=$(wanpipemon -i w1g1 -c astats -m 2 | grep -m1 VOLT | cut -d ":" -f 2-2)
LINE3=$(wanpipemon -i w1g1 -c astats -m 3 | grep -m1 VOLT | cut -d ":" -f 2-2)
LINE4=$(wanpipemon -i w1g1 -c astats -m 4 | grep -m1 VOLT | cut -d ":" -f 2-2)
LINE5=$(wanpipemon -i w1g1 -c astats -m 5 | grep -m1 VOLT | cut -d ":" -f 2-2)
LINE6=$(wanpipemon -i w1g1 -c astats -m 6 | grep -m1 VOLT | cut -d ":" -f 2-2)

echo "Line 1 Voltage: $LINE1"
echo "Line 2 Voltage: $LINE2"
echo "Line 3 Voltage: $LINE3"
echo "Line 4 Voltage: $LINE4"
echo "Line 5 Voltage: $LINE5"
echo "Line 6 Voltage: $LINE6"

Running the script on the machine via the terminal it works great perfect really. In my PHP script I simply do this (the php script is on the same server as the sh file):

<?php
    $output = shell_exec('/usr/sbin/linesta.sh');
    echo "<pre>$output</pre>";
?>

The output I recieve in the browser running the script is:

Line 1 Voltage:
Line 2 Voltage:
Line 3 Voltage:
Line 4 Voltage:
Line 5 Voltage:
Line 6 Voltage:

Now I have made sure that the permissions are correct, well should already know that since it runs 50% of the way, and like I have said I know that the script works on the machine.

It is just really weird because of the fact that it outputs the static text but not the dynamic text. The command 'wanpipemon -i w1g1 -c astats -m *' is part of the driver application for the analog card on my PBX and does not need root to run it (any user can run the command) so it confuses me as to what is going on.

Any help and/or debugging advice will be much appreciated, thus far I have only tried double checking permissions on the shell script, running the script on the server in console (linesta.sh that is) but i am unsure what else to test. I have tried the other PHP commands such as exec() and system() with the exact same results.

标签: php linux shell
2条回答
时光不老,我们不散
2楼-- · 2019-07-14 22:58

Is wanpipemon in the path of whatever shell PHP's using to execute the script? The 'file not found' type errors would be written to stderr and not trapped by your string building in the script, and also not caught by PHP unless you did stderr redirection:

$output = shell_exec('/usr/sbin/linesta.sh 2>&1');
                                           ^^^^--- redirect stderr to stdout.
查看更多
3楼-- · 2019-07-14 23:02

There are plenty of particular thing with shell_exec I use the following function to get all output

/**
 * Executes the shell command and gets stdout and stderr streams
 *
 * @see http://www.php.net/manual/en/function.proc-open.php
 * @param string $cmd - command to be executed
 * @param string $cwd - folder
 * @param array $env - options
 * @return array()
 */
function shexec($cmd, $cwd = './', $env = array())
{
    $return_value = array(
         "exit"   => 1,       // exit 0 on ok
         "stdout" => "",      // output of the command
         "stderr" => "",      // errors during execution
    );

    $descriptorspec = array(
    0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
    1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
    2 => array("pipe", "w")   // stderr is a pipe
    );

    $process = proc_open(escapeshellcmd($cmd), $descriptorspec, $pipes, $cwd, $env);
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // 2 => readable handle connected to child stderr

    if (false === is_resource($process))
    {
        //echo("Sys::shexec() Error on proc_open, shell command \"$cmd\"");
    }
    else
    {
        $return_value['stdout'] = stream_get_contents($pipes[1]);
        $return_value['stderr'] = stream_get_contents($pipes[2]);

        fclose($pipes[0]);
        fclose($pipes[1]);
        fclose($pipes[2]);

        // It is important that you close any pipes before calling
        // proc_close in order to avoid a deadlock
        $return_value['exit'] = proc_close($process);
    }

    if(trim($return_value['stderr']) !== "") {
        //echo("Sys::shexec() \n\"$cmd\"\nERROR:\n" . $return_value['stderr']);
    }

    if(trim($return_value['stdout']) !== "") {
        //echo("Sys::shexec() \n\"$cmd\"\nOUTPUT:\n" . $return_value['stdout']);
    }

    return $return_value;

} // END FUNCTION shexec()
查看更多
登录 后发表回答