# 指令執行

Agent 執行 shell 指令時套用的規則。

`run_command` 永遠不會拿到原始 shell 字串。argv-only 輸入、強制裸指令名，以及經解析（而非樣式比對）的 `sh -c` 腳本，構成三道防線——完整規則見沙箱頁。背景版本（v1.3.1）套用同樣的規則；`run_command_background` 更名為 `background_command`（移除於 v1.3.2）。位於唯讀 allowlist 的指令（v1.3.3 起內建 532 筆，v1.3.0 移除 `cd` 後為 409 筆；自 v1.0.25 起比對執行檔加最多兩個參數：`git status`、`docker ps`、`ls`...）跳過 confirm gate，但任一參數為敏感路徑或呼叫設定 `network: true` 時除外；其餘皆由當前權限模式控管，且 `auto` 下的不可逆指令（破壞性的 Git、基礎設施、雲端、部署、migration 或 SQL 操作）即使命中 allow 規則仍會詢問。自 v1.3.3 起唯讀判定移到 `internal/agents/exec/readonly`：可設值或載入外掛的指令（`date`、`hostname`、`sysctl`、`nm`、`objdump`）逐指令檢查參數，`--version`／`-v` 條目須整個 argv 相符，git 全域旗標只收明列項，會啟動外部程式的 git 選項（`--ext-diff`、`--textconv`、`-O`）一律不放行；`sh -c`／`bash -c` 腳本須每個內層指令都命中，且不含變數賦值、`export`、`printf -v`、算術與參數展開。命中的呼叫會並行執行。自 v1.3.3 起 `run_command`／`background_command` 的確認另附一句由 dispatcher model 寫的說明。Sandbox 內的網路預設關閉，除非該次呼叫設定 `network: true`（v1.0.25）；此時 `safe` 下需確認，`auto` 下直接執行。自 v1.3.0 起 `sandbox: false` 可讓單一指令在沙箱外執行，不論權限模式或 allow 規則，都必須先通過使用者的系統密碼驗證。自 v1.3.2 起也接受 argv `['sudo', '<binary>', ...]`：它會發起一律要求系統密碼的 `sudo: <cmd>` 確認（sudo ticket 仍有效時不顯示密碼欄位），之後在沙箱外以 `sudo -n <binary> ...` 執行；`sh -c` 內的 `sudo` 仍會被拒絕。v1.3.11 起，argv 含本 daemon 產生過的密鑰遮罩值（見[安全模型](/zh/security)）即拒絕，因此需要金鑰的指令在同一次呼叫內讀取，例如 `['sh', '-c', 'set -a; . ./.env; set +a; curl ...']`。

自 v1.3.0 起，TUI 中以 `!` 開頭的輸入會把其餘內容當成使用者自己下的 shell 指令：以 `$SHELL -c`（未設定則 `/bin/sh`）在 TUI 的工作目錄、以使用者本身的權限執行，不經沙箱也不經 confirm gate，上限 30 分鐘；結束後把 exit code 與輸出（上限 32 KiB）交給 agent 回報。自 v1.3.2 起，含 `sudo` 的 `!` 指令在沒有有效 sudo ticket 時會先跳出密碼視窗，以 `sudo -S -v` 驗證後才執行；密碼錯誤時顯示 `[Denied] password: incorrect password`。

指令政策是**拒絕清單**而非允許清單：`config.json` 的 `denied_command` 是唯一清單，不在其上的指令都可執行，但仍受 sandbox 與確認機制約束。舊的 `white_list` / `path_white_list` 鍵已不再讀取，`sensitive_map` 已更名為 `sensitive_path`——設定檔若仍留有這些鍵會被靜默忽略（啟動警告已於 v1.1.2 移除）。
