Über ein Skript geöffnete Shell-Registerkarte bleibt nach Strg+C bei laufendem Prozess hängen

Über ein Skript geöffnete Shell-Registerkarte bleibt nach Strg+C bei laufendem Prozess hängen

Ich habe folgendes Skript:

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

Beide Befehle hängen von den Umgebungseinstellungen ab (chrubyKonfiguration), sodass ich meine ./zshrcDatei vor dem Ausführen desforemanJuwel.

Wenn ich dies jedoch ausführe und dann versuche, Ctrl+Cden lange laufenden Prozess zu beenden, wird die Shell beendet und ich erhalte meine Eingabeaufforderung nie wieder.

Hinweis: Wenn ich „foreman start“ in einer neuen Shell im selben Verzeichnis ausführe, wird mir die Eingabeaufforderung danach zurückgegeben Ctrl+C.

Bearbeiten: Die Leute scheinen sich daran zu verzweifeln, dass Foreman das Problem sei, was meiner Meinung nach aber nicht der Fall ist, da dies beispielsweise bei laufenden ./gradlew bootRunoder jedem anderen lang laufenden Prozess hängen bleibt.

Foreman verlässt uns definitiv:

^CSIGINT received
16:13:09 system       | sending SIGTERM to all processes
16:13:10 api.1 | exited with code 130

Genauso wie 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%

An diesem Punkt kann ich nichts tun – alles wird ignoriert und ich muss die Registerkarte schließen.

Antwort1

Was Sie beobachten, ist eine Kombination aus zwei Dingen:

  1. Strg-C sendet INT an die Prozessgruppe, was bedeutet, dass nicht nur Ihr lang laufender Prozess, sondern auch einzshDer Prozess, in dem es ausgeführt wird, wird gleichzeitig beendet (und es besteht keine Möglichkeit, dass es neu gestartet wird).

  2. xfce4-terminal schließt die Registerkarte aufgrund des Flags -H nicht, nachdem Ihr Prozess beendet ist:

−H, −−hold Bewirkt, dass das Terminal erhalten bleibt, nachdem der Child-Befehl beendet wurde

wodurch es aussieht, als ob es hängt

Ein möglichst einfacher Testfall hierfür könnte etwa so aussehen:

CMD=xeyes
START=$'/usr/bin/zsh -c \''$CMD$'; /usr/bin/zsh\''
xfce4-terminal --tab -H -T mycommand --working-directory=$HOME -e "$START"

Wenn Sie dies starten, werden die "xeyes" Ihnen folgen, bis Sie drückenStrg+C, an diesem Punkt werden sie geschlossen und es scheint, als ob Ihr Terminal hängt.

Aber wenn Sie statt aufStrg+CSie beenden einfach die xeyes selbst (mit xkill oder der Taskleiste des Fenstermanagers),zshDie Sitzung wird wie vorgesehen gestartet.

Eine Problemumgehung hierfür besteht darin, das SIGINT abzufangen und die Shell wie folgt neu zu starten:

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"

Beachten Sie, dass Sie möglicherweise auch „-H“ entfernen möchten, damit die Registerkarte geschlossen wird, wenn Sie die Shell verlassen.

verwandte Informationen