A guia Shell aberta via script trava após Ctrl + C na execução do processo

A guia Shell aberta via script trava após Ctrl + C na execução do processo

Eu tenho o seguinte 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 os comandos dependem das configurações do ambiente (chrubyconfiguração), então eu forneço meu ./zshrcarquivo antes de executar oforemangema.

No entanto, se eu executar isso e tentar Ctrl+Csair do processo de longa execução - o shell termina e nunca recebo meu prompt de volta.

Nota: executar o foreman start em um novo shell no mesmo diretório retorna o prompt para mim depois de Ctrl+C.

Editar: as pessoas parecem estar ficando preocupadas com o fato de o capataz ser o problema, o que acredito não ser o caso, pois isso depende da execução ./gradlew bootRunou de qualquer processo de longa execução.

Foreman definitivamente sai:

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

Assim como a inicialização do Spring:

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%

Neste ponto não há nada que eu possa fazer - tudo é ignorado e tenho que fechar a aba.

Responder1

O que você observa é uma combinação de duas coisas:

  1. Ctrl-C envia INT para o grupo de processos, o que significa que não apenas o seu processo de longa execução, mas também umzshprocesso em que está sendo executado será encerrado simultaneamente (e não terá a chance de se reiniciar).

  2. xfce4-terminal, não fechará a aba, após o término do processo, devido ao sinalizador -H:

−H, −−hold Faz com que o terminal seja mantido por perto após o comando filho terminar

o que faz parecer que está pendurado

Um caso de teste mais simples possível para isso pode ser algo assim:

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

Se você iniciar isso, os "xeyes" estarão seguindo você, até você pressionarCtrl+C, ponto em que eles serão fechados e seu terminal parecerá estar travado.

Mas se em vez de clicarCtrl+Cvocê apenas matará os próprios xeyes (ou seja, com um xkill ou uma barra de tarefas do gerenciador de janelas), umzsha sessão começará conforme planejado.

Uma solução alternativa para isso é interceptar o SIGINT e reiniciar o shell, assim:

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"

Observe que você também pode querer remover '-H', para fechar a guia, ao sair do shell.

informação relacionada