Claude Code 背景 Bash 完整教學 — 讓 dev server 在背景跑,AI 邊寫程式邊盯 log
你叫 Claude 跑 npm run dev,畫面上那行 log 開始滾,然後就停住了。你打字,沒反應。它不是當機,它是在乖乖等這個指令跑完。可是 dev server 根本不會跑完。這一等,就是無限久。
卡住的那一秒,Claude 其實正在做一件很具體的事。搞懂那件事,解法就自己浮出來了。
對話卡住的那一秒,Claude 在等什麼
Claude 跑指令的預設方式是同步的。一次工具呼叫,等於開一個 shell、把指令丟進去、站在那裡等它吐完所有輸出、拿到 exit code,這一整包收回來,這一回合才算結束。
對一個三秒跑完的 ls 來說,完全沒差。你根本感覺不到那三秒。
但 dev server 不一樣。vite、jest --watch、docker compose up 這種東西的設計就是不結束。它要一直活著監聽埠、一直重編譯、一直等下一個 request。於是那個「等它結束」的動作永遠等不到,整個對話就跟著凍在那一格。
Claude 沒壞。它只是被綁在一個永遠不會結束的指令上,動不了。
背景執行做的事:把電話改成簡訊
想像同步就是講電話:你得等對方講完、掛掉,你才能做下一件事。dev server 是那種永遠不掛電話的對象。
背景執行做的,是把這通電話改成傳簡訊。指令一丟出去,Claude 立刻收到一張回條,上面寫著一個編號,比方 bash_1。這一回合馬上結束,你又能打字了。那個指令呢?它沒被殺掉,它被搬到旁邊繼續跑。
官方文件把這個描述得很直白:Claude Code 用非同步的方式跑指令,立刻回一個背景任務 ID,然後就能繼續回應你新的訊息,而那條指令在背景照跑不誤。
輸出被導進一個檔案,這步是命脈
這裡有個設計值得停下來看。指令搬到背景之後,它的輸出不再直接回給那一回合,而是被導進一個檔案。Claude 想知道 dev server 現在噴了什麼,就去 Read 那個檔案。
這一步看起來不起眼,其實是整個機制的命脈。
為什麼?因為 dev server 的 log 是會滾的。每一個 request、每一次 hot reload,都吐好幾行。如果這些全部塞回對話,你的 context 十分鐘就被 log 灌爆。導進檔案,就把這條噴泉關進了水管:Claude 每次去看,只撈上次看過之後的新內容,不必從頭讀一遍。
一個聒噪到不行的 process,可以在背景吵一整天,而你的對話乾乾淨淨。你甚至可以叫 Claude「去看 bash_1 裡有沒有紅字」,它就只把 log 裡的錯誤抓出來,其他略過。
它的壽命綁在你的 session 上
接著看它活多久。這個背景 process 現在綁在誰身上?綁在你這個 Claude Code session。
session 還活著,它就活著。你關掉 Claude Code,它會被一起收掉。這是刻意的:免得你關了視窗,一堆孤兒 dev server 還在背景偷占你的埠。想讓它撐過關機那一刻也行,把整個 session 丟到背景,而不是直接退出,這些任務就交棒給背景 session 繼續顧。
三道保險,跟一個 CI 陷阱
官方還埋了三道保險。
第一,單一背景任務的輸出超過 5GB,直接掐掉,並在 stderr 留一句話說明原因,免得某個瘋狂噴 log 的程式把你硬碟寫爆。第二,在 macOS 跟 Linux 上,如果 session 閒置超過 30 分鐘、又沒有任何回合在跑,系統一喊記憶體吃緊,背景任務會被回收(v2.1.193 之後加的)。第三,你要是根本不想要這功能,設一個環境變數 CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1,整套關掉。
還有個坑得先記著:如果你把 Claude Code 塞進 CI,背景任務多半是災難。CI 要的是「跑完、給我 exit code、往下一步」,背景任務偏偏是「我先閃了、之後再說」。dev server 在背景起來,job 卻已經往下衝,下一步一連線就 connection refused。所以進 CI 前,把上面那個環境變數關掉,讓所有指令乖乖同步跑完。
反過來看,它到底幫你省下什麼
機制拆完了。現在反過來,看這東西實際幫你省下什麼。
最直接的一招:dev server 丟背景,然後叫 Claude 一邊改 code 一邊盯它的 log。你改了一個 component,存檔,hot reload 觸發,server 那邊噴了個紅字。以前你得自己切到那個終端機、複製那段 stack trace、貼回來。現在 Claude 自己去 Read log 檔,看到錯,直接改。它等於長了第二雙眼睛,一隻手寫 code,另一隻盯著跑起來的東西。
我自己最有感的是跑前端:改完 Tailwind 存檔,Claude 直接從 log 看到 PostCSS 報的錯,我不用在兩個終端機之間跳來跳去,也不用當那個複製貼上 log 的人肉水管。這件事聽起來很小,但一天下來省掉的切換次數,比你想像的多。
跑一整套要三分鐘的測試也一樣。丟背景,Claude 趁這三分鐘先去改別的檔案,測試跑完再回頭收結果。以前那三分鐘是純乾等,現在變成能幹活的三分鐘。build、docker、terraform 這種慢吞吞的傢伙,通通適用。
兩個按鍵,一個 /tasks
要把指令丟背景,有兩條路。
一條是直接跟 Claude 講「幫我在背景跑 dev server」,它會自動用 Bash 工具的背景參數。另一條更快:在 Claude Code 裡輸入開頭打一個驚嘆號,進 shell mode,像 ! npm run dev,這行會直接在你的 shell 跑、不用 Claude 批准;等它開始滾 log,按 Ctrl+B,就推到背景了。用 tmux 的人要注意,Ctrl+B 是 tmux 自己的前綴鍵,所以你得連按兩次它才吃得到。
想看現在背景跑著哪些東西,打 /tasks,它會列出所有還在跑的 shell 跟 subagent、各自的狀態。要停掉,最省事的就是叫 Claude「把背景那個 dev server 關掉」,它會自己找到對的 process 收工。
別跟背景子代理搞混
有兩個名字很像的東西,得畫清界線。
背景執行跑的是 shell 指令,是 dev server、是 build、是測試這種活生生的 process。背景子代理跑的是一整個 subagent,一個會自己讀檔、自己思考的分身。前者你丟出去的是一條命令,後者你丟出去的是一個任務。兩個都叫「背景」,但一個管的是 process 的生死,一個管的是對話會不會卡住。搞清楚你手上要丟的是哪一種,才不會用錯工具。
說到底,它解開的是兩條時間線
退一步看,背景執行真正動到的,不是多一個按鍵或多一個指令。它動的是一件更底層的事:把「這個 process 要活多久」跟「這一回合對話要跑多久」這兩條時間線解開。
這其實是電腦科學裡最老的一招。你的作業系統早就在幹同樣的事:你按下存檔,它不會讓整台電腦停在那裡等硬碟寫完,它把寫入丟到背景,你繼續打字。瀏覽器在背景載圖片,資料庫在背景刷 buffer,全是同一個念頭:誰慢,誰就滾去背景,別擋住前面的人。Claude Code 只是把這個幾十年的老智慧,搬進了你跟 AI 的對話裡。
所以下次 dev server 又讓你的對話凍住,先別怪 AI 笨。它只是還在等一通永遠不會掛的電話。你要做的,就是伸手按下 Ctrl+B,幫它把電話改成簡訊。





























































