即使發生錯誤,PHP exec 命令也有結果 0
我有這個 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 的退出狀態重新啟動
ssh
或rsh
始終為0
.