애플리케이션 X가 tmux 창의 전경에서 실행되고 있다고 가정합니다. SIGUSR1이라는 특정 신호를 애플리케이션 X로 보내고 싶습니다. 현재 선택된 창의 전경 프로세스(또는 프로세스 그룹)에 신호를 보내도록 tmux 키 바인딩을 구성할 수 있나요?
답변1
내 쿠분투에서는 ps
프로세스가 연결된 터미널의 전경 프로세스 그룹 ID를 제공합니다. 키워드는 입니다 . 로 식별된 프로세스 tpgid
에 대한 쿼리를 전달하면 이 창에서 포그라운드 프로세스 그룹 ID를 얻게 됩니다.ps
tmux
#{pane_pid}
다음 바인딩(in ~/.tmux.conf
) 은 prefixkSIGUSR1을 포그라운드 프로세스 그룹(기본값 prefix은 Ctrl+ 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)"
그러나 다음과 같은 경우에는 여전히 실패합니다.아니요하위 프로세스(즉, 창의 포그라운드 프로세스는 셸 자체입니다).
물론, 견고성을 한 단계 더 끌어올려야 한다면 쉘 스크립트로 옮겨서 실제로 존재하는지 확인하세요.예신호를 보내기 전에 자식 프로세스입니다.