エラーが発生しても、PHP execコマンドの結果は0です。

エラーが発生しても、PHP execコマンドの結果は0です。

このPHPコードがあります。

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

このコードでは常に。$result = 0が提供されます。スモーキングにエラーがある場合は、コマンドラインに次のコマンドを入力するとエラーが表示されることがあります。

ssh [email protected] "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毎回ゼロのような値を与えます。 (エラーはないか)

execコマンドはなぜこのように動作します(phpとCLIで)?

答え1

存在する

ssh [email protected] "sudo /etc/init.d/smokeping reload"

あなたの殻

(1)(またはあなたの例ではPHPが起動したシェルexec())コマンドラインを解析し、見つかったら実行します。ssh

(2) 連絡順sshd

(3)xxx.xxx.xxx.xx認証成功後のサーバコールshell

(4) コマンドラインを解釈してsudo実行します。sudo

(5) 権限確認後に実行する命令/etc/init.d/smokeping

(6)それ自体が複数のコマンドを実行するシェルスクリプトです。

失敗する可能性があるいくつかの点があります。ステップ1~5がすべて成功すると、実行したコマンドの終了状態を/etc/init.d/smokeping報告するため、終了状態がシェルに報告され、リモートシェルは、実行した最後のコマンドの終了状態で終了して報告されます。リモートシェルの終了状態です。sudossh

慣例に従って、コマンドはゼロ以外の終了ステータスを返し、要求された操作が完了していないことを呼び出し側に報告します。

あなたの場合に/etc/init.d/smokeping発生するエラーは、ゼロ以外の終了状態を保証するのに十分ではないと見なされるか、スクリプトが誤って書き込まれ、失敗した場合はゼロ以外の終了状態に返されません(または誤動作またはいくつかの病理学的条件が含まれます)。sshまたはsudoリモートシェル設定エラー)。

/etc/init.dスクリプトは通常を使用して作成されますset -e。このフラグを有効にすると、実行中のコマンドが失敗した場合(失敗したコマンドの終了状態がゼロではない)、スクリプトを解釈するシェルがデフォルトで終了するため、最初のケースになる可能性があります。 :「スモーク」実際にリロードに成功したと報告することにしました。

病理学的状況の例は次のとおりです。bashリモートシェルとして使用され(対話型シェルでなくても呼び出し時に読み取られるbash)、次のようになります。~/.bashrcssh~/.bashrc

trap 'whatever...; exit 0' EXIT

sshこれにより、インタラクティブシェルまたはシェルが再起動されるか、rsh常に状態で終了します0

答え2

2>&1私は小さな答えを見つけました。上記のコードは最後に置きました。 〜のように

$execout=exec('ssh [email protected] "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. )

これでここで処理できます。みんなありがとうございます。

関連情報