PHP shell_exec()とexec()


345

私は違いを理解するのに苦労していますshell_exec()exec()...

私はいつもexec()サーバー側のコマンドを実行するために使用してきましたが、いつ使用しますshell_exec()か?

shell_exec()省略形exec()ですか?パラメータが少ない同じことのようです。


2
違いを確認する良い例では、これらのコマンドを試してみることです:datewhoamiifconfignetstat

他の関数もあります:system()、passthru()…この関連する質問、特にこの回答を参照してください。
Gras Double

回答:


353

shell_execすべての出力ストリームを文字列として返します。execデフォルトでは出力の最終行を返しますが、すべての出力を2番目のパラメーターとして指定された配列として提供できます。

見る


21
exit-valueとすべての出力が必要な場合は、おそらく「shell_exec」ではなく「exec」を使用する方が良いでしょう。出力パラメーターを「exec」に渡すとすぐに、出力のすべての行で埋められます。「exec」は「shell_exec」などのすべてを実行できるようです:)
Preexo

4
@ daniel-a-white私はこれが古いものであることを知っていますが、人気があるので、@ preexoによって作成されたコメントを反映するように回答を編集する必要があります-exec ()は、オプションのパラメーターを使用する場合、出力全体を返す機能もあります。また、無関係で、誰かが2つのコマンドのベンチマークを行って、@ preexoが「すべて[できる]や[もっと]できるように思えるのでexec()shell_exec()、どちらが適切かを確認する必要があります。」
SimpleAnecdote

77

ここに違いがあります。最後の改行に注意してください。

> shell_exec('date')
string(29) "Wed Mar  6 14:18:08 PST 2013\n"
> exec('date')
string(28) "Wed Mar  6 14:18:12 PST 2013"

> shell_exec('whoami')
string(9) "mark\n"
> exec('whoami')
string(8) "mark"

> shell_exec('ifconfig')
string(1244) "eth0      Link encap:Ethernet  HWaddr 10:bf:44:44:22:33  \n          inet addr:192.168.0.90  Bcast:192.168.0.255  Mask:255.255.255.0\n          inet6 addr: fe80::12bf:ffff:eeee:2222/64 Scope:Link\n          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1\n          RX packets:16264200 errors:0 dropped:1 overruns:0 frame:0\n          TX packets:7205647 errors:0 dropped:0 overruns:0 carrier:0\n          collisions:0 txqueuelen:1000 \n          RX bytes:13151177627 (13.1 GB)  TX bytes:2779457335 (2.7 GB)\n"...
> exec('ifconfig')
string(0) ""

バックティック演算子の使用はと同じであることに注意してくださいshell_exec()

更新:最後の1つは本当に説明する必要があります。何年も後にこの回答を見ると、なぜそれが空白になったのかわかりません!ダニエルは上でそれを説明しています-それexecは最後の行だけを返すからであり、ifconfig'の最後の行はたまたま空白です。


コマンドでエラーが1つ発生するとどうなりますか?エラー/ No such file or directoryが表示されますが、どうすれば変数にキャプチャできますか????
Happy Coder 2013年

@AlwinAugustin:えっ?STDERRに書き込まれている可能性があります。2>&1Linuxマシンを使用している場合は、コマンドの最後に追加して、STDERRをSTDOUTにリダイレクトしてください。
mpen 2013年

私もそれを追加しました。しかし、まだ値として0を取得しています。私は1つのwc -lコマンドを使用しましたが、ファイルがそこにない場合、そのようなファイルまたはディレクトリはありませんというエラーメッセージを取得する必要があります。
Happy Coder

50

shell_exec-シェル経由でコマンドを実行し、完全な出力を文字列として返します

exec -外部プログラムを実行します。

違いは、shell_exec出力を戻り値として取得することです。


4
素敵な簡潔な要約!exec出力の最後の行を返すことに注意してください。必要に応じて、オプションで配列を2番目のパラメーターとして渡して完全な出力をキャプチャし、3番目のパラメーターとして整数を渡してシェルコマンドの戻り値をキャプチャし、エラーチェックに使用できます。最大の欠点shell_execは、コマンドが失敗した場合、または出力を生成しない場合にnullを返すため、戻り値をエラーチェックに確実に使用できないことです。
Sean the Bean

38

ここでは触れなかったいくつかの違い:

  • exec()を使用すると、出力行の配列を受け取るオプションのparam変数を渡すことができます。場合によっては、特にコマンドの出力がすでに表形式である場合に、これにより時間を節約できることがあります。

比較:

exec('ls', $out);
var_dump($out);
// Look an array

$out = shell_exec('ls');
var_dump($out);
// Look -- a string with newlines in it

逆に、コマンドの出力がxmlまたはjsonの場合、入力を他の形式に後処理する必要があるため、各行を配列の一部として使用することは望ましくありません。その場合は、shell_execを使用してください。 。

また、shell_execは、* nixに使用されているものに対して、backtic演算子のエイリアスであることを指摘する価値もあります。

$out = `ls`;
var_dump($out);

execは、実行されたコマンドからの戻りコードを提供する追加のパラメーターもサポートします。

exec('ls', $out, $status);
if (0 === $status) {
    var_dump($out);
} else {
    echo "Command failed with status: $status";
}

shell_execのマニュアルページに記載されているように、実行中のコマンドからの戻りコードが実際に必要な場合は、execを使用するしかありません。


3
さらに:execコマンドの戻りコードを(&$return_varパラメーターを介して)取得できますが、取得するshell_exec方法はありません。
Mark Amery 2014年

受け入れられた答えも正しいですが、私の意見では、この答えはより重要です。おそらく、最良の答えは両方の組み合わせでしょう。
UncaAlby
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.