PHP system()、exec()、shell_exec() 的 差異

PHP 要呼叫 Shell 執行程式的時候, 偷懶有 `ls` 可以使用, 不過, 正規點可以使用 system()、exec()、shell_exec() 這三個 Function 來操作.

system()exec()shell_exec() 這三個 Function 使用上有何差異呢?

PHP system()、exec()、shell_exec() 的 差異

system()、exec()、shell_exec() 官方文件說明如下:

  • system — Execute an external program and display the output
    • string system ( string $command [, int &$return_var ] )
  • exec — Execute an external program
    • string exec ( string $command [, array &$output [, int &$return_var ]] )
  • shell_exec — Execute command via shell and return the complete output as a string
    • string shell_exec ( string $cmd )

一般系統會有兩種輸出, 一種是系統狀態(return code), 一種是輸出文字(output string), 這三個 Function 主要就是這些回傳的差異.

  • system()
    • $last_line = system('ls', $return_var);
    • system() 會將輸出內容直接印出, 所以若於網頁, 會將所有回傳內容都顯示於頁面上.
    • $last_line: 只能取得最後一行的內容
    • $return_var: 取得系統狀態回傳碼
  • exec()
    • exec('ls', $output, $return_var);
    • $output: 回傳內容都會存於此變數中(儲存成陣列), 不會直接秀在頁面上.
    • $return_var: 取得系統狀態回傳碼
  • shell_exec()
    • $output = shell_exec('ls');
    • $output: 回傳內容都會存於此變數中(儲存成純文字內容), 不會直接秀在頁面上.

範例程式

由此範例執行一次就比較容易理解. (請建立一個目錄, 隨便放兩個檔案, 再將此程式放置執行)

<?php
echo "\nsystem";
$last_line = system('ls', $return_var);
echo "\nreturn_var:";
print_r($return_var);
echo "\nlast_line:";
print_r($last_line);

echo "\n\nexec";
exec('ls', $output, $return_var);
echo "\nreturn_var:";
print_r($return_var);
echo "\noutput:";
print_r($output);

echo "\n\nshell_exec";
$output = shell_exec('ls');
echo "\noutput:";
print_r($output);
?>

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

在〈PHP system()、exec()、shell_exec() 的 差異〉中有 11 則留言

  1. 大師,

    請問使用 exec() 時如何設定 Asychronize 執行?
    我的程式如下:
    for($i=0; $i<3; $i++) {
    exec("php-cli sleep.php ".$id);
    }

    sleep.php 執行時間約10秒,我整個程式跑完是30秒。要如何讓三個 sleep.php一起執行?(*我有傳遞一個變量 $id)

  2. 大師,我想要透過PHP網頁方式,輸出AD裡dsquery computer之類的訊息,我用shell_exec指令去下,只解出error.log:'dsguery' 不是內部或外部命令、可執行的程式或批次檔。(本機CMD可以下dsquery computer的指令並得出結果)

    如下:
    echo "\n\nshell_exec";
    $output = shell_exec('ls');
    echo "\noutput:";
    print_r($output);

    'ls'可以秀出電腦資料,但是換成'dsquery computer domainroot -name * -desc xxx'就會是不是內部或外部命令…
    有沒有其它的建議方式呢???謝謝。

    1. STDOUT 這類的問題吧..

      你試試看 dsquery computer ... > 1.txt,1.txt 應該是沒有資料的

      再來測試看看 dsquery computer ... 2&> 1.txt 看看

  3. 你好 我想請教一下 如果SNMP讀寫 效能來說 會建議使用這三個FUNCTION的哪一個嗎?
    又或者建議使用PHP SNMP本身的FUNCTION呢?

  4. 在一个遍历里,我需要持续通过exec内的output获取返回参数,每次执行的结果应该是不一样的,但是为什么output这个变量不会被重新赋值?比如,执行了10次的循环,但是最后output的值还只是第一次的结果

    1. 會阿,不過要注意他的 output 參數是 reference

      string exec ( string $command [, array &$output [, int &$return_var ]] )

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料