제 직장에는 SLURM에서 관리하는 고성능 컴퓨팅 클러스터가 있습니다.
일부 사람들의 작업은 하나의 작업으로 많은 프로세스를 생성합니다. 또한 최상위 컨트롤러를 잘못 작성하므로 SIGINT로 인해 자식 프로세스가 좀비가됩니다.
이 환경의 특성으로 인해 (실제로 타당한 이유없이)이 문제를 해결하기를 기대하는 것은 합리적이지 않습니다.
그래서 나는 작업이 끝나면 모든 자식 프로세스를 죽일 제출 래퍼를 만들려고합니다.
ps
기본적으로 현재 tty 세션과 관련된 모든 프로세스를 가져옵니다. 그러나 SLURM은 어리석은 작업을 수행하며이 ps
작업의이 작업에 대한 프로세스뿐만 아니라 다른 작업도 수행하므로 하나의 작업이 죽을 때마다 물리적 노드의 모든 것을 죽입니다.
그렇다면 현재 bash 스크립트의 자식 인 모든 작업을 어떻게 가져 오거나 종료합니까?
현재 프로세스 (스크립트 프로세스 또는 쉘)는 $$에 저장됩니다. 해당 PID를 사용하여 -P 플래그와 함께 pgrep 명령을 pgrep -P $$
사용하여 상위 PID가 다음과 같은 모든 PID 목록을 가져올 수 있습니다.$$
다음은 매우 간단한 개념 증명 스크립트입니다.
#!/bin/bash
curpid="$$"
#launch 2 useless child processes
cat /dev/random > /dev/null &
cat /dev/random > /dev/null &
cpid=`pgrep -P $curpid` && echo "$(basename $0) pid: $curpid; child pids:" $cpid
#kill the child pids
kill $cpid
# check if any child pids still exist
newcpid=`pgrep -P $curpid`
if [ $? -ne "0" ] || [ "$newcpid" != "" ]; then
echo "no child pids left..."
else
echo $newcpid
fi
산출:
{0} 02:34:57] $ ./test3.sh
test3.sh pid: 7015; child pids: 7016 7017
./test3.sh: line 12: 7016 Terminated cat /dev/random > /dev/null
./test3.sh: line 12: 7017 Terminated cat /dev/random > /dev/null
no child pids left...
다른 사용자 (예 : sudo)로 자식 프로세스를 시작하면 부모라도 프로세스를 종료 할 수있는 권한이 없을 수 있습니다. 다음 중 하나를 변경하면
cat /dev/random > /dev/null &
라인
sudo cat /dev/random > /dev/null &
해당 프로세스를 종료 할 수 없습니다 (일반 사용자 계정으로 스크립트를 처음 시작했다고 가정).
수정 된 스크립트 (하위 하나를 루트로 실행하고 끝에 diff 정보 출력) :
#!/bin/bash
curpid="$$"
#launch 2 useless child processes
cat /dev/random > /dev/null &
sudo cat /dev/random > /dev/null &
cpid=`pgrep -P $curpid` && echo "$(basename $0) pid: $curpid; child pids:" $cpid
#kill the child pids
kill $cpid
sleep 0.5
#check on children
for i in $cpid; do
echo -n "PID: $i; Orig PPID: $curpid; Cur PPID: "`/usr/bin/ps --ppid $i | grep -Eo '[0-9]{3,}'`
echo
done
자식 중 하나가 루트로 실행되는 출력 :
[{0} 02:53:51] $ ./test3.sh
test3.sh pid: 8144; child pids: 8145 8146
./test3.sh: line 9: kill: (8146) - Operation not permitted
./test3.sh: line 10: 8145 Terminated cat /dev/random > /dev/null
PID: 8145; Orig PPID: 8144; Cur PPID:
PID: 8146; Orig PPID: 8144; Cur PPID: 8150
루트로 시작된 자식 PID는 더 이상 초기 스크립트를 부모로 간주하지 않고 대신 sudo 호출로 만든 하위 셸입니다. 의 출력 ps auxf
은이를 명확하게 보여줍니다.
root 8146 0.0 0.0 244996 7444 pts/2 S 02:54 0:00 sudo cat /dev/random
root 8150 0.0 0.0 113828 744 pts/2 S 02:54 0:00 \_ cat /dev/random
이 문제는 질문의 핵심이 아니라 명심해야 할 문제입니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다