
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 (chruby
Konfiguration), sodass ich meine ./zshrc
Datei vor dem Ausführen desforeman
Juwel.
Wenn ich dies jedoch ausführe und dann versuche, Ctrl+C
den 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 bootRun
oder 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:
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).
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.