sandbox_procs

列出、等待或停止用 sandbox_exec 加 background: true 開的命令,也能用 execId 拿取或等待前景命令。用它,不要用 pkill -f 或 pgrep -f:命令列含有那個 pattern 的程序都會被比對到,別的工作也算。

輸入 輸出
id、action(list,預設;wait 或 stop)、bgId(背景的 bgId 或前景的 execId;wait 與 stop 必填;list 時只看那一個)、all(只用於 list)、tailBytes(1 到 16384)、timeoutSec(只用於 wait:預設 600,最多 600)、until(只用於 wait:exit,預設;或 ready)、readyPort 與 readyLog(只用於 wait) list:procs[{bgId, running, note, cmd, startedAt, logPath, mine, cpu, exitCode, signal, endReason, finishedAt, readyWhen, ready, readyAt, logTail}] 與 foreground[…],有已結束的沒列出時另有 finished 與 hint;只看一個命令(bgId)時另有 steps,已結束的前景命令另有 result;wait:proc 與 stillRunning(等準備好時另有 ready);stop:proc 與 stopped

用 sandbox_exec 加 background: true 開的每個命令都有 bgId,輸出寫到它的 logPath,也就是 /work/.sbx/logs/<bgId>.log。sandbox_procs 管這些命令:

sandbox_procs { "id": "<id>" }
sandbox_procs { "id": "<id>", "action": "list", "bgId": "<bgId>" }
sandbox_procs { "id": "<id>", "action": "wait", "bgId": "<bgId>", "timeoutSec": 300 }
sandbox_procs { "id": "<id>", "action": "stop", "bgId": "<bgId>" }
  • list(不給 action 也是它)回 { "procs": [...] }:還在跑的背景命令,先開的在前,各有 bgId、running、note(給 sandbox_exec 的那句)、cmd(前 120 個字,密鑰的值已遮掉)、startedAt、logPath、cpu(它所有程序的 %CPU 加總;100 是一個核心)與 mine(是不是這個對話開的)。foreground 用同樣的方式列出此刻正在跑的前景命令,來自所有在用這個箱子的對話,bgId 放的是它們的 execId:好幾個對話共用的箱子上,看 cpu 與 mine 就知道是誰的工作在用這台機器。有已結束的沒列出時,finished 寫有幾個、hint 寫怎麼看。all: true 連已結束的也列,各附 exitCode(還在跑的沒有這一欄)。給 bgId 就只回那一個,不管還在不在跑,附 logTail,也就是 log 的結尾。
  • 一般的 list 不帶 logTail。帶 bgId 的 list、wait 與 stop 回 log 的最後 4096 個位元組;tailBytes(1 到 16384)改要幾個位元組,一般的 list 也適用。裡面密鑰的值會換成 ****(sandbox_exec),log 檔本身不改。
  • wait 會等到那個命令結束,或 timeoutSec 用完(預設 600,最多 600),回 { "proc": {...}, "stillRunning": false },proc 附 exitCode。時間先用完時回 stillRunning: true,不是錯誤:再呼叫一次。背景跑的長 build 或測試用它等,不要在 sandbox_exec 裡用 sleep 輪詢。
  • until: "ready" 則改成命令一準備好就回:它的 readyPort 接受連線,或 log 有一行比對到 readyLog(兩者都是給 sandbox_exec 的),附 ready: true 與 readyAt。把 readyPort 或 readyLog 傳給 wait,會替開的時候沒設條件的命令設定(或取代)這個條件,並等同 until: "ready";log 從頭開始找,所以呼叫之前印出的行也算。命令還沒準備好就結束的話,wait 回它已結束,附 ready: false。
  • 前景命令的 execId 可以當 bgId 用:還在跑時,用它呼叫 list 與 wait 會顯示它,附 foreground: true,到目前為止的輸出放在 logTail;結束後,proc.result 放的是它的 sandbox_exec 回的東西(stdout、stderr、exitCode、truncated、durationMs、timedOut,輸出被截斷時還有 outputPath)。那次呼叫被切斷時就用它。最近 200 個前景結果會保留。
  • steps(只在看單一命令時)列出 psbx-step 在其中記下的東西:每個步驟的 name、exitCode、ms 與 startedAt,還在跑的那個附 running: true(見 sandbox_exec)。
  • 被訊號結束的命令有 signal,endReason 說是誰送的:stopped by sandbox_procs stop、out-of-memory killer(箱子記憶體不夠了),或別的程序。
  • stop 結束命令的整個 process group:先送 SIGTERM,5 秒後還有東西在就送 SIGKILL。命令起的程序會一起結束,所以經 npx 或 npm run 起的 server 也會停,port 也會空出來。回 { "proc": {...}, "stopped": true },被停掉的命令 exitCode 是 -1。對已經結束的命令,回它原本的狀態。
  • 背景命令用這個停,不要在 sandbox_exec 裡用 pkill -f 或 pgrep -f。命令是從腳本檔跑的,pattern 不會再打到跑你這次 sandbox_exec 的 shell,但命令列含有它的其他程序都會被比對到,別的背景工作也算。不是用 background 起的程序,用只比對完整程序名稱的 pkill -x <名稱>。kill <pid> 只送訊號給那一個程序,它起的程序(例如 npx 底下的 server)可能還在跑。stop 會結束整個群組。
  • 背景命令記在 /work/.sbx/procs,所以箱子的 agent boxd 重啟(更新、當掉、因記憶體被砍掉)之後還在:還在跑的照樣列得出來、停得掉;boxd 停著的期間結束的,exitCode 是 -1,endReason 說它真正的結束碼不明。用比這更舊的映像開的箱子,boxd 重啟後會失去這份記錄,回 bgId not found。
  • 錯誤:箱子不認得的 bgId 回 box <id>: bgId not found: …,附上可能的原因;wait 或 stop 沒給 bgId 回 bgId is required: list them first with action list;其他的 action 回 action must be list, stop or wait。
  • 每次呼叫都跟其他工具一樣算使用箱子,所以用 wait 等很久的工作時,箱子不會因為閒置而被凍結;對凍結的箱子會先喚醒(箱子狀態)。背景命令在凍結與解凍之後繼續跑,最多讓箱子在最後一次使用後保持醒著 1 小時。在前景 sandbox_exec 裡用 & 起的程序不在其中:這個工具列不到也停不了它,起它的那次呼叫會以 leftoverChildren: true 註明(sandbox_exec)。

所有工具與主題都列在工具參考。