****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.
好的我有一个简单的shell脚本运行命令并输出FXO线电压,通常你必须一次得到一行,这一行将它们组合成一个可读输出。 (与这篇文章无关,但我认为有人可能会问这个剧本的作用)
这是shell脚本:
#!/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"
通过终端在机器上运行脚本,它确实非常完美。在我的PHP脚本中,我只是这样做(php脚本与sh文件在同一服务器上):
<?php
$output = shell_exec('/usr/sbin/linesta.sh');
echo "<pre>$output</pre>";
?>
我在运行脚本的浏览器中收到的输出是:
Line 1 Voltage:
Line 2 Voltage:
Line 3 Voltage:
Line 4 Voltage:
Line 5 Voltage:
Line 6 Voltage:
现在我确保权限是正确的,应该已经知道,因为它运行了50%,就像我说的那样,我知道脚本可以在机器上运行。
这真的很奇怪,因为它输出的是静态文本而不是动态文本。命令'wanpipemon -i w1g1 -c astats -m *'是我的PBX上模拟卡的驱动程序应用程序的一部分,并且不需要root运行它(任何用户都可以运行命令)所以它让我困惑的是什么正在进行。
我们非常感谢任何帮助和/或调试建议,到目前为止我只尝试了对shell脚本的双重检查权限,在控制台的服务器上运行脚本(linesta.sh)但我不确定还有什么去测试。我尝试过其他PHP命令,如exec()和system(),结果完全相同。
答案 0 :(得分:2)
PHP用于执行脚本的shell的路径中是wanpipemon
吗? “找不到文件”类型错误将被写入stderr并且不会被脚本中的字符串构建捕获,除非您执行stderr重定向,否则也不会被PHP捕获:
$output = shell_exec('/usr/sbin/linesta.sh 2>&1');
^^^^--- redirect stderr to stdout.
答案 1 :(得分:1)
shell_exec
有很多特别之处我使用以下函数来获取所有输出
/**
* 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()