2011-07-21 171 views
2
****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. 

好吧,我有一個運行命令,並輸出FXO線電壓一個簡單的shell腳本,通常你會在某一時刻得到一個線這個結合他們到一個可讀的輸出。 (不相干的這篇文章,但我想有人會問這個腳本做什麼)PHP了shell_exec() - 不打印動態輸出,只打印靜態回聲文本

這是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

我最終什麼事做了分配cron作業運行腳本,cron作業將要運行腳本,並採取輸出,並將其寫入到文件中, PHP將通過readfile獲取信息。不是最好的解決方案,但對我來說,我想是夠了。只是想我會補充我在這裏所做的,以便其他任何想要監視模擬線路的人都可以輕鬆地做到這一點。 – BrandonS

回答

2

wanpipemon在PHP的任何shell的路徑下用來執行腳本嗎? 「文件未找到」類型的錯誤都會被寫入標準錯誤,而不是在腳本中被困的串樓,除非你做標準錯誤重定向也不會被PHP抓:

$output = shell_exec('/usr/sbin/linesta.sh 2>&1'); 
              ^^^^--- redirect stderr to stdout. 
+0

看看輸出結果如下:Ioctl ::操作不允許,我猜php腳本運行的用戶級別沒有足夠的權限來運行wanpipemon,至少這是我從輸出中得到的。我真的不知道哪裏的腳本是誠實的,就像我說的那樣,它是模擬卡驅動程序的一部分,我會嘗試找到並查看。有關在更高級別運行php腳本的任何建議? – BrandonS

+0

有suPHP,它可以讓你以不同的用戶身份運行腳本,你可以嘗試在你的shell_exec調用中使用sudo,等等...... –

+0

你是對的,它是權限。即使使用根(我知道它不安全只是測試)使用-S開關將不起作用這是wanpipemon編程的方式,這是問題,但您的解決方案確實允許我進一步診斷並且實際上發現問題如此謝謝。猜測我將不得不在控制檯中使用它。 – BrandonS

0

有很多特別的東西用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()