실행 중인 프로세스에서 Ctrl+C를 누른 후 스크립트를 통해 열린 셸 탭이 중단됩니다.

실행 중인 프로세스에서 Ctrl+C를 누른 후 스크립트를 통해 열린 셸 탭이 중단됩니다.

다음 스크립트가 있습니다.

#!/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

이 두 명령은 모두 환경 설정(chruby./zshrc구성) 따라서 실행하기 전에 파일을 소싱합니다.foreman보석.

그러나 이것을 실행한 다음 Ctrl+C장기 실행 프로세스를 종료하려고 하면 셸이 종료되고 프롬프트가 다시 표시되지 않습니다.

참고: 동일한 디렉토리의 새 셸에서 foreman start를 실행하면 이후에 프롬프트가 반환됩니다 Ctrl+C.

편집: 사람들은 감독관이 문제가 되는 것에 매달리는 것 같습니다. 이는 실행 중인 말하기 ./gradlew bootRun또는 장기 실행 프로세스와 관련이 있기 때문에 사실이 아니라고 생각합니다.

포먼은 확실히 퇴장합니다.

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

스프링 부트도 마찬가지입니다:

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%

이 시점에서는 제가 할 수 있는 일이 없습니다. 모든 것이 무시되고 탭을 닫아야 합니다.

답변1

당신이 관찰하는 것은 다음 두 가지의 조합입니다.

  1. Ctrl-C는 INT를 프로세스 그룹으로 보냅니다. 이는 장기 실행 프로세스뿐만 아니라zsh실행 중인 프로세스는 동시에 종료됩니다(그리고 자체적으로 다시 시작할 기회는 없습니다).

  2. xfce4-terminal은 -H 플래그로 인해 프로세스가 끝난 후 탭을 닫지 않습니다.

−H, −−hold 하위 명령이 종료된 후에도 터미널이 유지되도록 합니다.

매달린 것처럼 보이게 만드는

이에 대한 가장 간단한 테스트 사례는 다음과 같습니다.

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

이것을 실행하면 "xeyes"가 다음을 누를 때까지 따라다닐 것입니다.Ctrl+C, 그 시점에서 닫히고 터미널이 정지된 것처럼 보입니다.

하지만 클릭하는 대신Ctrl+Cxeye 자체를 종료하면 됩니다(예: xkill 또는 창 관리자 작업 표시줄 사용).zsh세션이 의도한 대로 시작됩니다.

이에 대한 해결 방법은 다음과 같이 SIGINT를 가로채서 셸을 다시 시작하는 것입니다.

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"

쉘을 종료할 때 탭을 닫으려면 '-H'를 제거해야 할 수도 있습니다.

관련 정보