跳到主要內容

退出碼

每條 arc 命令都用退出碼報告結果——0 表示成功,另有七個各不相同的非零值(其中一個已預留但還沒有產出)——指令碼不用讀報錯文本就知道遇到的是哪一類失敗。

每條 arc 命令退出時都帶一個可供指令碼分支判斷的數字。非零值不止一個,正是關鍵所在:"你要的路徑不在"、"你把命令拼錯了"、"沒有 daemon 在跑",這三件事需要指令碼做三種不同的反應,而分辨它們不該依賴去匹配英文報錯文本。

退出碼含義適用範圍
0命令做了你要它做的事所有命令
1不在——或者,對 service start 來說,已經在了所有命令
2權限拒絕已預留——這個版本里沒有命令會返回它(見下文)
3例項有記錄但沒有在跑(stoppedstartingarc service status
4例項記錄說它在跑,但它的處理程序已經沒了(deadarc service status
5執行時錯誤,所有用法錯誤都算在內所有命令
6這條命令需要一個 daemon,而沒有 daemon 在跑所有命令
7在沒有 llm renderer 的命令上要求了 --view llm任何命令的 --view llm

注意"適用範圍"這一列。上面的 34arc service status 對例項記錄的自有解讀,並不是對整個 CLI 的承諾:在別處這兩個數字表示執行時的通用含義——3 是衝突,4 是部分成功——而且 4 有真實的產出方,就是一批 arc did issue 裡有的 provider 成功、有的失敗的情況。把 rc == 4 讀成"daemon 死了"的指令碼,會把那一批誤判。只在 arc service status 上按 4 分支。

2 在列舉裡,但這個版本沒有任何產出點。下面 2 那一節寫了這是怎麼核實出來的,不是拍腦袋斷言。7 的適用範圍很窄:它只在 --view llm 上觸發,而且只在沒有 llm renderer 的命令上;每條命令依然接受 --view default / --view json / --view human

下面每一節都是對應場景的一次真實執行,對照的是 arc 2.0.0-beta.48(構建 5a5316bde,2026-09-10)。單看版本號分不清你手上是哪個構建——2.0.0-beta.48 這一輪週期裡已經指過不止一個二進位制——所以在相信這頁上任何輸出逐位元組一致之前,先跑一遍 arc --version,把它的第三個欄位(commit)跟這裡寫的對一下。這張表要讀作"這些碼分別是什麼意思",而不是"arc 可能返回的全部數字":以別的方式失敗的命令同樣以非零退出,後續版本也可能新增退出碼。

0 —— 命令做了你要它做的事

bash
$ arc service list
NAME          ID                PORT   STATUS   HOME                          SOURCES
(no instances)

結果為空同樣是成功。沒東西可列不是失敗——去要一個具體的、而它不在,這才會拿到 1

1 —— 不在,或者已經在了

讀一個不存在的路徑:

bash
$ arc afs read /no-such-file --instance notes
ERROR: No data found for path: /no-such-file

指名一個從未建立過的例項:

bash
$ arc service status --instance nope
ERROR: no instance named "nope". `arc service list` shows 1

以及——這條值得記住——去 start 一個已經起著的例項:

bash
$ arc service start --instance notes
ERROR: instance "notes" is already running
       pid 93652, port 61430, started 15s ago
       use `arc service restart --instance notes` or pick another name

最後這條是 1,不是 5。這個碼的意思是"你點名的東西不處於你需要的狀態",既涵蓋"它不存在",也涵蓋"它已經存在了"。這不是用法錯誤,所以不是 5

2 —— 權限拒絕,定義了但還沒有產出

執行時的退出碼列舉把 2 留給了 PermissionDeniedError,這個類確實存在於 CLI 自己的錯誤模組裡。但這個版本里沒有任何東西丟擲它:沒有命令會構造 PermissionDeniedError,而 CLI 之下 AFS 層丟擲的權限失敗也沒有被轉譯成它——它就那樣原樣繼續往上傳播,跟其他沒被特殊處理的失敗一樣落到 5。這一條是核實過的,不是假設:拿 chmod 000 做出一個讀不了的檔案,直接復現了真實行為。

bash
$ arc afs read /vault/locked.txt --standalone
ERROR: EACCES: permission denied, open '/tmp/arc-perm-test/secret/locked.txt'

這條命令退出碼是 5。把 2 當作協議預留給一個 CLI 目前還沒做出區分的數字,而不是實踐中會遇到的一個。

3 —— 例項存在,但沒有在跑

bash
$ arc service stop --instance notes
Service stopped: notes
$ arc service status --instance notes
  Instance: notes
  ID:       ab5aa97074c454a0
  Status:   stopped
  PID:      93652
  Port:     61430
  URL:      http://127.0.0.1:61430
  Home:     /tmp/arc-docs-demo/notes
  Note:     PID / Port / URL above are the LAST KNOWN values from this instance's previous run, not a live process.

上面省略了 VersionCommitCheckoutSpaceSourcesHostStarted 幾個欄位。停掉之後 pid、port、URL 照樣報出來,Note: 那行明確說了這些是歷史值——--json 裡同一件事表現為 lastKnown 標記。

starting 同樣返回 3,這一點在你寫"等它起來"的迴圈時很要緊:3 的意思是"還沒就緒",不是"起不來了"。冷啟動時這個視窗有幾秒鐘,輪詢 status 會依次看到 stoppedstarting(退出 3)→ up(退出 0)。把 3 當作"繼續等",把 4 當作"別等了"。

4 —— 記錄說它在跑,但處理程序已經沒了

正常的命令序列走不到這裡,因為這個碼描述的是損壞,而不是某種選擇。要看到它,就起一個例項,然後直接殺掉它的 daemon,讓登錄檔那行仍然聲稱 up,而背後的處理程序已經不存在:

start 自己也會列印一整塊狀態;下一步要用的 pid 就在它的 PID: 那行。下面兩塊都只截取了這裡用得上的欄位。

bash
$ arc service start --instance notes --home /tmp/arc-docs-demo/notes
  Instance: notes
  Status:   up
  PID:      95288
  Port:     61430
  Home:     /tmp/arc-docs-demo/notes
$ kill -9 95288
$ arc service status --instance notes
  Instance: notes
  ID:       ab5aa97074c454a0
  Status:   dead
  PID:      95288
  Port:     61430
  URL:      http://127.0.0.1:61430
  Home:     /tmp/arc-docs-demo/notes
  Note:     PID / Port / URL above are the LAST KNOWN values from this instance's previous run, not a live process.

崩潰、被 OOM 殺掉、機器重啟——任何沒走 arc service stop 就結束了處理程序的情況,拿到的都是 dead。跟 3 分開是有價值的:stopped 是有人選擇的狀態,dead 是沒有人選擇的狀態。arc service gc 清理的正是且僅是這個狀態的記錄。

5 —— 執行時錯誤,用法錯誤也算

這是覆蓋面最寬的一個碼。把命令列寫錯的每一種方式都落在這裡。下面三種在你看到的內容之後還會繼續列印用法說明——第一種列印完整命令列表,另外兩種列印該命令自己的幫助。未知命令:

bash
$ arc serivce list
ERROR: Unknown command: "serivce"

Did you mean?
  arc serve
  arc service

未知選項:

bash
$ arc service list --bogus
ERROR: Unknown argument: bogus

缺少必填引數:

bash
$ arc space rm
ERROR: Not enough non-option arguments: got 0, need at least 2

以及越過命令列之後,執行時無法路由的請求:

bash
$ arc afs exec /no-such-action --instance notes
ERROR: No module found for path: /no-such-action in namespace 'default'

5 同樣覆蓋"命令跑對了、但報告了一個真實世界的問題"——arc network doctor 只要有檢查失敗就以 5 退出。所以單看 5 並不能告訴你是你寫錯了、還是外面有東西壞了;那是報錯文本的職責。

6 —— 這條命令需要 daemon,而沒有 daemon 在跑

bash
$ arc afs ls /
ERROR: No AFS daemon is running for instance "default".
Start it with:  arc service start
Or use --standalone for ad-hoc mode (no runtime state)

第二行的建議命令只會照抄你實際打過的那些引數——不帶 --instance--home 就建議裸的 arc service start;自己傳了 --instance foo --home ~/foo,它就照原樣建議回去,絕不會冒出一個你沒打過的值。6 存在,就是為了讓這種情況不讀報錯文本也能跟 5 區分開。"前置條件沒滿足、起個 daemon 就能解決"跟"命令執行失敗"是兩回事,而報錯文本把修法寫出來了。指名的例項其 daemon 處於 stoppeddead 時,回來的同樣是 6,不只是 default 才這樣。

7 —— 要求了 --view llm,但這條命令渲染不了

--view llm 是全域都接受的,但不是每條命令都有 llm renderer 來處理它,而一個沒實現的會 fail closed,不會悄悄退回預設檢視。arc network doctor 沒有 llm renderer:

bash
$ arc network doctor --view llm
ERROR: --view llm is not implemented for `network doctor`. This command has no llm renderer (declare ⇒ execute; will not silently fall back to default).

arc afs ls 是實現了的,同一個 flag 用在支援它的命令上就會成功:

bash
$ arc afs ls / --standalone --view llm
ENTRY /spaces CHILDREN=-1 DESC="Local DID Space logical roots"
ENTRY /peers CHILDREN=-1 DESC="Dispatchable ARC hosts (always includes local)"
ENTRY /ash CHILDREN=-1 DESC="ASH pipeline DSL for deterministic data pipelines"
ENTRY /dev CHILDREN=-1
ENTRY /modules CHILDREN=-1
ENTRY /team CHILDREN=-1
ENTRY /.knowledge KIND=afs:system CHILDREN=-1 DESC="Provider capability index"
ENTRY /.meta KIND=afs:system CHILDREN=-1 DESC="Root metadata and mount info"
ENTRY /.actions KIND=afs:system CHILDREN=-1 DESC="Root-level executable actions"
TOTAL 9

對指令碼來說要緊的區分在這裡:一個不認得的 --view 值(比如 --view bogus)是引數解析就抓到的用法錯誤,跟其他寫錯的 flag 一樣退出 5——

bash
$ arc service list --view bogus
ERROR: Invalid values:
  Argument: view, Given: "bogus", Choices: "default", "llm", "human", "json"

——而在沒有 llm renderer 的命令上用 --view llm,是一個合法、認得出的值,只是這條命令目前實現不了,退出 7。沒有這個區分,指令碼就沒法不解析英文文本地分辨"我把 flag 打錯了"和"flag 是對的,只是這條命令還不支援"。