La pestaña Shell abierta mediante script se bloquea después de Ctrl+C en el proceso en ejecución

La pestaña Shell abierta mediante script se bloquea después de Ctrl+C en el proceso en ejecución

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 (chrubyconfiguración) así que obtengo mi ./zshrcarchivo antes de ejecutar elforemanjoya.

Sin embargo, si ejecuto esto y luego intento Ctrl+Csalir 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 bootRuno 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:

  1. 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).

  2. 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.

información relacionada