
我有以下腳本:
#!/usr/bin/env zsh
START_FOREMAN='/usr/bin/zsh -c "source /home/user/.zshrc; foreman start" zsh'
xfce4-terminal --tab -H -T app-server --working-directory=/home/user/git/app -e $START_FOREMAN
xfce4-terminal --tab -H -T api-server --working-directory=/home/user/git/api -e $START_FOREMAN
這兩個命令都取決於環境設定(chruby
配置),所以我./zshrc
在運行之前獲取我的文件foreman
寶石。
但是,如果我運行此命令,然後嘗試Ctrl+C
退出長時間運行的進程 - shell 會結束,並且我永遠不會得到提示。
注意:在同一目錄中的新 shell 中執行 foreman start 後會傳回提示符號給我Ctrl+C
。
編輯:人們似乎對工頭的問題感到困擾,但我認為情況並非如此,因為這與運行./gradlew bootRun
或任何長時間運行的進程有關。
工頭肯定退出:
^CSIGINT received
16:13:09 system | sending SIGTERM to all processes
16:13:10 api.1 | exited with code 130
與 Spring boot 一樣:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:291)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at org.gradle.process.internal.streams.ExecOutputHandleRunner.run(ExecOutputHandleRunner.java:51)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
:bootRun FAILED
> Building 100%
此時我無能為力 - 一切都被忽略,我必須關閉選項卡。
答案1
您觀察到的是兩件事的組合:
Ctrl-C 將 INT 傳送到進程組,這表示不僅是您長時間運行的進程,還包括桀騁它正在運行的進程將同時終止(並且它不會有機會重新啟動)。
xfce4-terminal,由於 -H 標誌,在進程結束後不會關閉選項卡:
-H, --hold 使終端在子命令終止後保持不變
這使得它看起來像是懸掛著的
最簡單的測試案例可能如下所示:
CMD=xeyes
START=$'/usr/bin/zsh -c \''$CMD$'; /usr/bin/zsh\''
xfce4-terminal --tab -H -T mycommand --working-directory=$HOME -e "$START"
如果您啟動此功能,「xeyes」將跟隨您,直到您按下Ctrl+C,此時它們將關閉,並且您的終端將顯示為掛起。
但如果不是點擊Ctrl+C你只需殺死 xeyes 本身(即使用 xkill 或視窗管理器工作列),桀騁會話將按預期開始。
解決此問題的方法是攔截 SIGINT 並重新啟動 shell,如下所示:
CMD=xeyes
START=$'/usr/bin/zsh -c \'trap "exec /usr/bin/zsh" INT;'$CMD$'; exec /usr/bin/zsh\''
xfce4-terminal --tab -H -T mycommand --working-directory=$HOME -e "$START"
請注意,您可能還需要刪除“-H”,以便在退出 shell 時關閉選項卡。