スクリプト経由で開かれたシェル タブは、実行中のプロセスで Ctrl+C を押すとハングします。

スクリプト経由で開かれたシェル タブは、実行中のプロセスで Ctrl+C を押すとハングします。

次のスクリプトがあります:

#!/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

これらのコマンドは両方ともenv設定に依存します(chruby./zshrc設定)なので、実行する前にファイルを読み込みますforeman宝石。

Ctrl+Cただし、これを実行してから長時間実行されているプロセスを終了しようとすると、シェルが終了し、プロンプトが表示されなくなります。

注: 同じディレクトリ内の新しいシェルで foreman start を実行すると、プロンプトが返されますCtrl+C

編集: 人々は Foreman が問題だと考えているようですが、これは実行中のプロセス./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

観察されるのは次の 2 つの要素の組み合わせです。

  1. Ctrl-CはプロセスグループにINTを送信します。つまり、長時間実行中のプロセスだけでなく、翻訳実行中のプロセスも同時に終了されます (再起動する機会はありません)。

  2. 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+Cxeyes自体を強制終了するだけです(つまりxkillやウィンドウマネージャのタスクバーで)。翻訳セッションは意図したとおりに開始されます。

この問題を回避するには、次のように SIGINT をインターセプトしてシェルを再起動します。

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」を削除することもお勧めします。

関連情報