我有以下脚本:
#!/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 时关闭选项卡。