
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 (chruby
configuração), então eu forneço meu ./zshrc
arquivo antes de executar oforeman
gema.
No entanto, se eu executar isso e tentar Ctrl+C
sair 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 bootRun
ou 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:
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).
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.