tmux 창에서 처리할 신호 보내기

tmux 창에서 처리할 신호 보내기

애플리케이션 X가 tmux 창의 전경에서 실행되고 있다고 가정합니다. SIGUSR1이라는 특정 신호를 애플리케이션 X로 보내고 싶습니다. 현재 선택된 창의 전경 프로세스(또는 프로세스 그룹)에 신호를 보내도록 tmux 키 바인딩을 구성할 수 있나요?

답변1

내 쿠분투에서는 ps프로세스가 연결된 터미널의 전경 프로세스 그룹 ID를 제공합니다. 키워드는 입니다 . 로 식별된 프로세스 tpgid에 대한 쿼리를 전달하면 이 창에서 포그라운드 프로세스 그룹 ID를 얻게 됩니다.pstmux#{pane_pid}

다음 바인딩(in ~/.tmux.conf) 은 prefixkSIGUSR1을 포그라운드 프로세스 그룹(기본값 prefixCtrl+ b)으로 보냅니다.

bind-key k run-shell 'kill -s USR1 -- "-$(ps -o tpgid:1= -p #{pane_pid})"'

노트:

  • 앞의 대시( -)는 $(…)전경 프로세스를 찾는 역할을 합니다.그룹. 대시 없이 시도할 수 있으며 하나의 프로세스만 대상으로 삼으면 해당 프로세스가 포그라운드 프로세스 그룹의 "리더"가 됩니다. 그러나 "리더"가 (여전히) 존재한다는 보장은 없습니다. 그룹을 타겟팅하는 것은 합리적인 접근 방식이며 Ctrl+ cSIGINT를 그룹에 보내는 것과 비슷하지만 메커니즘은 다릅니다.

  • :1이 답변에서 발췌 :ps공백 없이 명령 출력 형식을 설정합니다 .. 앞에 대시를 추가할 때 선행 공백을 제거하는 것이 중요합니다.

  • 경쟁 조건이 있습니다. kill이후에 실행되며 ps프로세스 그룹이 여전히 포그라운드에 있거나 전혀 존재한다는 보장이 없습니다.

  • 안타깝게도 prefixk대상으로 삼으려는 프로세스가 종료될 때 문제가 발생할 수 있습니다. 실수로 SIGUSR1을 다른 프로세스로 보낼 수 있습니다. 아마도 껍질일 겁니다. 그런 다음…

  • SIGUSR1의 기본 작업은 종료입니다.. 특히 포그라운드에 있는(즉, 명령을 기다리는) 대화형 셸은 prefixk.bash에서 실행될 수 있습니다. 미리 트랩을 설정하여 이를 방지할 수 있습니다.

    • trap '' USR1쉘이 신호를 무시하게 만듭니다. 이 경우 자식 프로세스는 명시적으로 신호를 처리하도록 선택하지 않는 한 신호를 무시합니다 dd.
    • trap : USR1쉘이 신호를 "무시"(아무것도 하지 않고 반응)하게 하지만 이는 하위 프로세스의 동작에 영향을 주지 않습니다.

답변2

Tmux는 이것을 제공 pane_pid하지만 이는 일반적으로 셸인 창에서 최상위 프로세스의 PID가 됩니다. 포그라운드 프로세스의 PID를 찾으려면 좀 더 자세히 살펴봐야 하지만 이를 pane_pid시작점으로 사용할 수 있습니다.

간단한 버전 - 다음과 같습니다:

bind k run-shell "kill -s SIGUSR1 $(cat /proc/#{pane_pid}/task/#{pane_pid}/children)"

창에 백그라운드 프로세스가 없으면 이것이 작동할 것이라고 생각합니다.

셸에서 여러 피어 프로세스가 실행 중이고 그 중 일부가 백그라운드에 있는 경우 상황은 더욱 복잡해집니다. 나는 ps -h --ppid #{pane_pid} -O stat하위 프로세스를 가져오는 데 사용과 같은 작업 pane_pid을 수행한 다음 그 중 어느 프로세스가 전경에서 실행되고 있는지 확인하고(즉, 열에 +하나가 있음 STAT) 해당 PID를 구문 분석해야 한다고 생각합니다 .

가능한 구현 중 하나는 다음과 같습니다.

bind k run-shell "kill -s SIGUSR1 $(ps -h --ppid #{pane_pid} -O stat | grep -o '^[[:blank:]]*[[:digit:]]\\+[[:blank:]]\\+[^[:blank:]]*+' | cut -d ' ' -f2)"

그러나 다음과 같은 경우에는 여전히 실패합니다.아니요하위 프로세스(즉, 창의 포그라운드 프로세스는 셸 자체입니다).

물론, 견고성을 한 단계 더 끌어올려야 한다면 쉘 스크립트로 옮겨서 실제로 존재하는지 확인하세요.신호를 보내기 전에 자식 프로세스입니다.

관련 정보