tmux Kill-window는 하위 프로세스를 종료하지 않습니다.

tmux Kill-window는 하위 프로세스를 종료하지 않습니다.

창에서 프로세스 를 종료 ctrl하고 ctmux 를 종료 하면 모든 하위 프로세스가 종료됩니다.ctrld

하지만 이렇게 하면:

ctrl+ b다음에 shift+%

그런 다음 Y를 선택하여 창을 종료하고 프로세스는 활성 상태로 유지됩니다. 창이 종료되면 프로세스도 종료되는지 확인하는 방법을 아시나요?

답변1

Ctrl+ c와 함께kill-window

일반적으로 Ctrl+를 사용하면 c( stty -a표시 될 때 intr = ^C) SIGINT를 다음으로 보냅니다.포그라운드 프로세스 그룹의 프로세스. SIGINT를 얻은 모든 프로세스가 종료(종료)될 것이라고 가정하는 것처럼 보이지만 일반적으로 그렇지 않을 수도 있습니다.

Ctrl+ 를 언급하셨으므로 dtmux 서버와 종료하려는 프로세스 사이에 대화형 셸이 있을 수 있습니다. 이 경우 SIGINT는 쉘이 아닌 프로세스로 전송되지만 쉘이 SIGINT를 가져오더라도 종료되지 않습니다. (항상 이렇다는 말은 아닙니다. 귀하의 설명에 적합하다고 말하고 있습니다.)

따라서 Ctrl+ 프로세스가 종료된 후 +를 눌러 쉘을 종료 c할 수 있습니다 .Ctrld

tmux에서 창을 종료하면 해당 의사 터미널이 닫히고 제어 터미널이 SIGHUP을 수신하는 것처럼 이를 사용하여 처리됩니다. 이러한 프로세스는 SIGHUP을 하위 프로세스로 보낼 수 있습니다(셸의 ​​경우 참조).이 답변). 프로세스는 이 신호를 무시할 수 있습니다(참고자료 참조 nohup). 신호를 무시하더라도 더 이상 존재하지 않는 의사 터미널을 사용하려고 하면 나중에 죽을 수도 있고 안 죽을 수도 있습니다.

간단히 말해서:

  • SIGINT 또는 SIGHUP을 관련 프로세스에 보냅니다.
  • SIGINT 또는 SIGHUP에 대한 반응 여부 및 방법은 프로세스에 따라 다릅니다..

SIGINT 보내기

프로세스는 SIGINT를 무시할 수 있습니다. Ctrl+가 작업 중인 프로세스에 대해 원하는 작업을 수행 하는 경우 c각 창에서 +를 누르는 것처럼 창을 종료하고 SIGHUP을 보내기 전에 SIGINT를 보내는 것으로 충분할 수 있습니다 Ctrl.c

다음 명령은 현재 창 창에 있는 프로세스(tmux 서버의 직계 하위 항목)를 나열하고 해당 포그라운드 프로세스 그룹을 얻은 후 각 프로세스에 SIGINT를 보냅니다.

tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{}

문제는 이 파이프도 SIGINT를 수신하여 조기 종료될 수 있다는 것입니다. 이 문제를 해결하려면

  • 다른 곳에서 명령을 실행하고 -t지정된 창을 사용합니다.
  • 또는 파이프의 전경 프로세스 그룹이 제외되도록 일부 논리를 구현합니다.
  • 또는 백그라운드에서 파이프라인을 실행합니다.

    tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{} &
    
  • 또는 명령이 신호를 무시하도록 만듭니다.

    sh -c '
    trap "" SIGINT
    tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{}
    '
    

나는 이 접근 방식 이 경쟁 조건에 취약하다고 생각합니다 ps. kill더 나은(?) 대안은 Ctrl+를 c각 창에 보내는 것입니다.

tmux list-panes -F "#{pane_id}" | xargs -I {} tmux send-keys -t {} C-c &

이 후크를 사용하면 tmux가 편집하려는 창의 모든 창에 +를 보내도록 할 수 있습니다 Ctrl.ckill-window

tmux set-hook before-kill-window 'run-shell "
   tmux list-panes -t \"#{window_id}\" -F \"##{pane_id}\" | xargs -I {} tmux send-keys -t {} C-c
"'

세 가지 수준의 참조가 있기 때문에 이는 좋지 않은 것처럼 보이지만 내 테스트에서는 여전히 작동하는 것 같습니다(아직 철저하게 테스트하지는 않았지만). 목적은 ##확장을 연기하는 것입니다 #{pane_id}. 요점은 작업하는 #{window_id}동안 확장이 필요 run-shell하지만 생존해야 하며 #{pane_id}출력을 생성할 때만 확장되어야 한다는 것입니다.list-panes

후크는 재정의되지만 , 또는 은 재정의 kill-window되지 않습니다 . 또한kill-panekill-sessionkill-serverkill-window아니요kill-pane몇 번만 반복했을 뿐이 므로 before-kill-pane 창을 강제로 파괴할 때 후크가 모든 경우를 커버하지는 않습니다. 그리고 respawn-pane -krespawn-window -k명령.


충분하지 않으면 어떻게 되나요?

프로세스는 SIGINT에서 종료되지 않을 수 있습니다. tmux list-panes -F "#{pane_pid}"시작점 으로 SIGTERM(또는 SIGKILL)을 보낼 PID(및/또는 PGID) 목록을 가져올 수 있습니다. 이 일반적인 접근 방식의 주요 문제점은 프로세스를 생성하고 해당 프로세스의 조상 및 tty와의 연결을 완전히 끊을 수 있다는 것입니다.

따라서 일반적으로 특정 tmux 창에서 발생하는 모든 프로세스를 추적하지 못할 수도 있습니다.

답변2

충분한 정보를 제공하지 않았습니다.

C-b %창을 분할해도 아무것도 종료되지 않으므로 키 바인딩을 변경해야 합니다. 바인딩이 있나요? 아니면 이라는 뜻인가요 C-b &?

킬 창은 pty를 닫고 커널은 pty를 제어 터미널로 사용하는 모든 프로세스에 SIGHUP을 보내 무시하지 않는 한 프로세스가 종료되도록 합니다.

창에서 정확히 무엇을 실행하고 있나요? 이러한 프로세스는 전혀 종료되지 않거나 좀비 프로세스가 되나요?

또한 사용 중인 tmux 버전을 아는 것도 도움이 될 수 있습니다.

관련 정보