
Tengo el siguiente script:
#!/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
Ambos comandos dependen de la configuración del entorno (chruby
configuración) así que obtengo mi ./zshrc
archivo antes de ejecutar elforeman
joya.
Sin embargo, si ejecuto esto y luego intento Ctrl+C
salir del proceso de larga duración, el shell finaliza y nunca recibo el mensaje.
Nota: ejecutar foreman start en un nuevo shell en el mismo directorio me devuelve el mensaje después de Ctrl+C
.
Editar: La gente parece estar obsesionada con que el capataz sea el problema, lo cual creo que no es el caso, ya que esto depende de la ejecución, por ejemplo, ./gradlew bootRun
o de cualquier proceso de larga duración.
Foreman definitivamente sale:
^CSIGINT received
16:13:09 system | sending SIGTERM to all processes
16:13:10 api.1 | exited with code 130
Al igual que 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%
En este punto no hay nada que pueda hacer: todo se ignora y tengo que cerrar la pestaña.
Respuesta1
Lo que observas es una combinación de dos cosas:
Ctrl-C envía INT al grupo de procesos, lo que significa que no solo su proceso de larga duración sino también unzshEl proceso en el que se está ejecutando finalizará simultáneamente (y no tendrá oportunidad de reiniciarse).
xfce4-terminal, no cerrará la pestaña una vez finalizado el proceso, debido al indicador -H:
−H, −−hold Hace que el terminal se mantenga disponible después de que el comando secundario haya terminado
lo que hace que parezca que está colgado
Un caso de prueba más simple posible para esto podría verse así:
CMD=xeyes
START=$'/usr/bin/zsh -c \''$CMD$'; /usr/bin/zsh\''
xfce4-terminal --tab -H -T mycommand --working-directory=$HOME -e "$START"
Si inicias esto, los "xeyes" te seguirán, hasta que presionesCtrl+C, momento en el que se cerrarán y parecerá que tu terminal está colgado.
Pero si en lugar de hacer clicCtrl+Csimplemente eliminarás los xeyes (es decir, con un xkill o una barra de tareas del administrador de ventanas), unzshLa sesión comenzará según lo previsto.
Una solución para esto es interceptar el SIGINT y volver a iniciar el shell, así:
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"
Tenga en cuenta que es posible que también desee eliminar '-H', para cerrar la pestaña, cuando salga del shell.