Shell 既是命令解釋器,也是程式設計語言(變量、循環、分支)。PHP 透過進程控制函數調用 Shell 腳本,常見場景:備份、文件傳輸、系統管理、長耗時任務異步化。
| 函數 | 返回值 | 輸出處理 | 典型適用場景 |
|---|---|---|---|
exec() | 最後一行輸出(字串) 可選第二參數接收完整輸出數組 | 不直接輸出,需手動處理 | 需捕獲命令結果進一步處理(如解析輸出行) |
shell_exec() | 完整輸出(字串) | 不直接輸出 | 簡單命令、不關心退出碼、需完整輸出文本 |
passthru() | 退出碼(整數) 直接輸出原始二進制流 | 直接輸出到瀏覽器/標準輸出 | 二進制輸出(圖片、PDF)、需即時流式傳輸、需檢查退出碼 |
system() | 退出碼 直接輸出最後一行 | 直接輸出 | 簡單交互命令、兼容舊代碼 |
<?php
// 權限檢查後,調用預寫好的 rsync 腳本
$script = '/usr/local/bin/xfer_rsync.sh';
$returnValue = 0;
// passthru 適合:需要即時輸出進度、且必須拿到退出碼判斷成敗
passthru($script, $returnValue);
if ($returnValue !== 0) {
// 記錄錯誤碼、發送告警郵件、寫入錯誤日誌
error_log("Rsync 失敗,退出碼: $returnValue");
// 返回錯誤頁面或 JSON
} else {
// 重定向成功頁面
header('Location: /transfer/success');
}
?>
Web 請求不應阻塞於耗時操作。推薦架構:
exec/passthru),捕獲退出碼與輸出優勢:符合 KISS 原則、無內存洩漏風險、進程自動退出無卡殼、易於監控與重試。
escapeshellarg()、escapeshellcmd() 轉義參數sudo、rm -rf 等高危命令PHP 與 Shell 協作無固定模板,根據輸出類型、是否需要退出碼、是否需流式傳輸在 exec/shell_exec/passthru 中選型。安全永遠是第一位約束,架構上推薦「Web 寫隊列 + Cron 讀隊列 + CLI 執行」解耦模式,實現高可靠、可觀測的異步任務體系。