Ssh

即使發生錯誤,PHP exec 命令也有結果 0

  • April 27, 2016

我有這個 PHP 程式碼:

$execout=exec('ssh root@xxx.xxx.xxx.xx "sudo /etc/init.d/smokeping reload"',$output1,$result);
if($result !=0){
   echo"that can't reload";
}
else{
   echo "successfully reloaded";
}

在這段程式碼中,總是給出$result = 0. 這是為什麼?有時如果smokeping有錯誤,它會在命令行中輸入以下命令時顯示該錯誤,

ssh root@xxx.xxx.xxx.xx "sudo /etc/init.d/smokeping reload"

然後它給出了這個錯誤資訊。

* Reloading latency logger daemon configuration...
ERROR: can't open /etc/smokeping/devices/errorfilename: No such file or   directory
...done.

所以它有一個錯誤,但$result每次都與 0 相同。(無論是否有錯誤)

為什麼 exec 命令的行為是這樣的(在 php 和 CLI 中)?

我為此找到了一個小答案。對於我放在2>&1最後的上述程式碼。作為

$execout=exec('ssh root@xxx.xxx.xxx.xx "sudo /etc/init.d/smokeping reload 2>&1"',$output1,$result);

當我要重新載入(吸煙)的應用程序中發生錯誤時,print_r($output);將錯誤顯示為

Array ( [0] => * Reloading latency logger daemon configuration... [1] => ERROR: can't open /etc/smokeping/devices/errorfilename: No such file or directory [2] => ...done. )

現在我可以從這里處理了。謝謝大家。

ssh root@xxx.xxx.xxx.xx "sudo /etc/init.d/smokeping reload"

你的外殼

(1)(或者在您的範例中,由 PHP 啟動的 shell exec())將解析該命令行,如果找到,則執行ssh

(2) 將聯繫a的命令sshd

(3)xxx.xxx.xxx.xx認證成功後呼叫的伺服器shell

(4) 它將解釋該sudo命令行並執行sudo

(5) 檢查權限後執行的命令/etc/init.d/smokeping

(6) 它本身可能是一個執行多個命令的 shell 腳本。

那裡有幾件事可能會失敗。如果所有步驟 1 到 5 都成功,則退出狀態/etc/init.d/smokeping將報告給您的 shell,因為sudo確實報告了它執行的命令的退出狀態,遠端 shell 以它執行的最後一個命令的退出狀態退出並ssh報告遠端 shell 的退出狀態。

現在,按照慣例,命令返回非零退出狀態,以向呼叫者報告他們沒有設法完成被要求做的事情。

在您的情況下,要麼/etc/init.d/smokeping決定發生的任何錯誤都不足以保證非零退出狀態,要麼該腳本編寫不正確並且在失敗時無法以非零退出狀態返回(或一些涉及不當行為的病態案例或或遠端 shell 的錯誤配置ssh) 。sudo

/etc/init.d腳本通常用set -e. 啟用該標誌後,預設情況下,解釋腳本的 shell 將在其執行的命令失敗時退出(失敗命令的退出狀態為非零),這讓我認為我們可能處於第一種情況:“吸煙”確實決定報告它已成功重新載入。

例如,一個病態案例的範例可能是:bash用作遠端外殼(即使那些不是互動式外殼,也會在呼叫時bash讀取),並且具有以下內容:~/.bashrc``ssh``~/.bashrc

trap 'whatever...; exit 0' EXIT

這將導致互動式 shell 或 shell 的退出狀態重新啟動sshrsh始終為0.

引用自:https://unix.stackexchange.com/questions/80869