저는 리눅스를 처음 접했습니다. 다른 파일에 Python 스크립트가 있으며 각 스크립트는 필요한 기능을 수행합니다.
foo1.py
foo2.py
foo3.py
이러한 각 스크립트는 종료하기 전에 정리되어야 합니다. 또한 터미널에서 각각을 실행하여 상호 작용하고 출력을 별도로 읽고 싶습니다.
다양한 종료 신호(예: SIGTERM, SIGINT 등)를 포착하기 위해 정리 기능을 구현했습니다.
터미널에서 각 스크립트를 실행하기 위해 아래와 같이 각 스크립트에 대한 터미널을 startup.sh
열어서 사용합니다.xterm
시작 파일
xterm -e python foo1.py & pid1=$!
xterm -e python foo2.py & pid2=$!
xterm -e python foo3.py & pid3=$!
그렇다면 내 논리에 따르면 스크립트가 foo3.py
가장 중요하므로 스크립트가 완료되면 나머지 두 개도 닫아야 합니다.
wait $pid3
kill -15 $pid1
kill -15 $pid2
문제는 script() 자체의 pid 가 아니라 xterm의 pid $pid1
입니다 . 따라서 xterms()를 종료하면 Python 스크립트는 정리 루틴을 실행할 기회를 얻지 못합니다.$pid2
foo.py
kill -15 $pid
xterm이 하위 프로세스(https://unix.stackexchange.com/a/54994/357513) 그러나 Python 스크립트는 즉시 완료됩니다.
그럼 얻을 수 있는 방법은 없을까?PIDxterm 내에서 실행되는 스크립트에서? 아니면 그러한 정리 루틴이 실행되도록 하는 다른 방법이 있습니까?
답변1
Python 스크립트도 SIGHUP
이를 포착하고 깔끔하게 종료해야 합니다. xterm이 실행 중인 의사 터미널을 해체할 때 그들은 하나를 얻습니다 SIGHUP
. 어쨌든 이 문제를 처리해야 합니다 SIGHUP
. 실행 중인 터미널이 xterm
명시적으로 종료되는 것 이외의 다른 이유로 사라질 수 있기 때문입니다(예: X11 서버 자체 종료).
EIO
또한 스크립트는 마스터 터미널이 없는 슬레이브 터미널에서 읽거나 쓰려고 할 때 오류를 올바르게 처리해야 합니다.
어쨌든 다음과 같이 Python 스크립트를 종료할 수 있습니다.
pkill -P $pid1
("부모에 의해 살해됨"; 참조맨페이지의 pkill
/ pgrep
)
모든 쉘이 스크립트의 마지막 명령을 fork/exec/wait에서 간단한 exec(예: debian 등)로 최적화하는 것은 아니므 dash
로 /bin/sh
복잡한 쉘 명령을 실행해야 하는 경우 exec
처럼 명시적으로 호출하는 것이 좋습니다 xterm -e 'script=$(...); exec python "$script"'
.
노트:
WINDOWID
질문에 정확하게 대답하지는 않지만 터미널 에뮬레이터에서 시작된 프로세스를 찾는 신뢰할 수 없지만 효과적인 방법은 해당 환경에 설정된 프로세스를 검색하는 것입니다.
pids_by_env(){ grep -aslP "\b($1)\0" /proc/[0-9]*/environ | grep -oP '\d+'; }
pids_by_window(){ pids_by_env "WINDOWID=$(printf '%d' "$(xwininfo "$@" | awk '/id:/{print$4}')")"; }
$ ps $(pids_by_window)
[click!]
PID TTY STAT TIME COMMAND
11244 pts/8 Ss 0:00 bash
11297 pts/8 S+ 0:00 vu [censored].pdf