2011-08-17 177 views
261

我努力理解shell_exec()exec()的區別...PHP了shell_exec()與EXEC()

我一直使用exec()執行服務器端的命令,當我會用shell_exec()

shell_exec()只是exec()的簡寫?這似乎是與更少的參數相同的東西。

+1

查看差異的一個很好的例子是嘗試下列命令:'date','whoami','ifconfig','netstat'。 –

+0

還有其他的功能:system(),passthru()...看到這個[相關的問題](https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru),特別是[這個答案](https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru#21016100)。 –

+0

[PHP的exec()vs系統()vs passthru()]可能重複(https://stackoverflow.com/questions/732832/php-exec-vs-system-vs-passthru) – jww

回答

276

shell_exec將所有輸出流作爲字符串返回。 exec默認返回輸出的最後一行,但可以將所有輸出提供爲指定爲第二個參數的數組。

參見

+18

如果您需要exit-值和所有的輸出你可能仍然更好地使用「exec」而不是「shell_exec」。只要你將輸出參數傳遞給「exec」,它將被輸出的每一行填充,在我看來,「exec」可以包含「shell_exec」和更多的所有內容:) – Preexo

+4

@ daniel-a-white我知道這是一箇舊的,但它很受歡迎,所以你應該編輯你的答案,以反映@preexo發表的評論 - [exec()](http://php.net/manual/en/function.exec.php)也有如果使用其可選參數,則可以返回整個輸出。此外,無關的,有人應該基準兩個命令,看看哪個更好,因爲@ preexo說:「在我看來,exec()'可以[做]所有的東西'shell_exec()'[can,]和更多:)_」 – SimpleAnecdote

41

shell_exec - 經由殼執行命令,並返回完整的輸出作爲一個字符串

exec - 執行的外部程序。

shell_exec不同的是,您將輸出作爲返回值。

+3

不錯的簡潔總結!應該注意的是'exec'返回輸出的最後一行。如果需要,您可以選擇傳入一個數組作爲第二個參數來捕獲完整的輸出,並將一個整數作爲第三個參數來捕獲shell命令的返回值,該命令可用於錯誤檢查。 'shell_exec'最大的缺點是,如果命令失敗或者它沒有產生任何輸出,它將返回null,所以它的返回值不能可靠地用於錯誤檢查。 –

57

以下是區別。注意最後的換行符。

> 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) "" 

注意,使用backtick operator的是相同的shell_exec()

更新:我真的應該解釋最後一個。看着這個答案多年後,我甚至不知道爲什麼會出現空白!丹尼爾解釋它 - 這是因爲exec只返回最後一行,ifconfig的最後一行恰好是空白。

+0

如果命令中出現一個錯誤,會發生什麼情況..?我得到錯誤/沒有這樣的文件或目錄,但我怎樣才能捕捉到一個變量? –

+0

@AlwinAugustin:哈?可能正在寫入STDERR。如果你在linux機器上,嘗試在你的命令的末尾添加'2>&1'來將STDERR重定向到STDOUT。 – mpen

+0

我也加了。但我仍然得到0的價值。我已經使用了一個wc -l命令,如果該文件不在那裏,我需要得到錯誤消息說沒有這樣的文件或目錄。 –

27

幾個區別了未在這裏觸及:

  • 與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的那些背景操作符的別名。

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

高管還支持額外的參數,將提供返回代碼執行命令:

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'沒有辦法獲得它。 –

+0

謝謝@MarkAmery我通過評論改進了答案。 – gview