스크립트에 의해 생성 된 모든 자식 프로세스의 목록을 얻는 방법


9

문맥:

사용자는 실행할 사용자 정의 스크립트를 제공합니다. 이 스크립트는 여러 GUI 프로그램, 백엔드 서비스를 시작하는 스크립트와 같은 종류 일 수 있습니다. 스크립트 작성 방법을 제어 할 수 없습니다. 이러한 스크립트는 차단 유형이 될 수 있습니다. 즉, 모든 하위 프로세스 (순차적으로 실행되는 프로그램)가 종료 될 때까지 실행 대기

#exaple of blocking script
echo "START"
first_program 
second_program 
echo "DONE"

또는 비 차단 유형, 즉 백그라운드에서 자식 프로세스를 포크하고 다음과 같은 것을 종료하는 유형

#example of non-blocking script
echo "START"
first_program &
second_program &
echo "DONE"

내가 무엇을 달성하려고합니까?

사용자 제공 스크립트는 위의 두 가지 유형 중 하나이거나 둘을 혼합하여 사용할 수 있습니다. 내 임무는 스크립트를 실행하고 시작한 모든 프로세스가 종료 될 때까지 기다렸다가 노드를 종료하는 것입니다. 차단 유형의 경우 대소 문자는 간단합니다. 즉 스크립트 실행 프로세스의 PID를 가져 와서 ps -ef | grep -ef PID에 더 이상 항목이 없을 때까지 기다립니다. 비 차단 스크립트는 문제를 일으키는 스크립트입니다.

스크립트 실행으로 생성 된 모든 자식 프로세스의 PID 목록을 얻을 수있는 방법이 있습니까? 모든 조언이나 힌트는 높이 평가 될 것입니다


부모의 PID를 캡처 할 수 없다면 부모 스크립트가 끝난 후에 가능하지 않다고 생각합니다. 스크립트를 시작하는 경우 pid$(foo.sh; echo $!)PID를 제공 하는 스크립트를 랩핑하여 foo.sh사용할 수 있습니다 ps --ppid. 작동합니까?
terdon

2
스크립트는 작성자 사용자의 UID에서 실행해야합니까? 그렇지 않은 경우이 목적으로 만 더미 사용자를 작성할 수 있습니까? 당신은 grep단지 필요하지 않을 것 ps –udummy_user입니다. 또한 프로세스 그룹을보십시오.
Scott

이것은 초기 질문에 대한 해결책보다 더 많은 해결 방법입니다. 새 bash 세션을여십시오. 당신은 사용이 쉘에서 만들어지는 모든 프로세스를 나열 할 수 있습니다 ps인수 (만해야하지를 bash하고 ps처음에). 거기서 스크립트를 시작하십시오. 완료 후 ps | wc -l예상 값에 도달 할 때까지 기다리 십시오.
Tim

답변:


8

질문에 직접 대답하기 위해

jobs -p

모든 하위 프로세스 목록을 제공합니다.

대안 # 1

그러나 귀하의 경우 wait매개 변수없이 명령 을 사용하는 것이 더 쉬울 수 있습니다 .

first_program &
second_program &
wait

모든 자식 프로세스가 완료 될 때까지 기다립니다 .

대안 # 2

또 다른 대안은 $!마지막 프로그램의 PID를 가져오고 다음과 같이 변수에 축적하는 것입니다.

pids=""
first_program &
pids="$pids $!"
second_program &
pids="$pids $!"

그런 다음 wait를 사용하십시오 (하위 프로세스의 하위 집합 만 기다리려는 경우).

wait $pids

대안 # 3

또는 모든 프로세스가 완료 될 때까지만 기다리려면 다음을 사용할 수 있습니다.

wait -n $pids

보너스 정보

bash 스크립트에 sigterm을 사용하여 자식 프로세스를 닫으려면 다음과 같이 신호를 전파해야합니다 (프로세스를 시작하기 전에 맨 위에 놓으십시오).

trap 'kill $(jobs -p)' SIGINT SIGTERM EXIT

1

귀하의 답변에 감사드립니다 .. 나는 stackoverflow에 대한 해결책을 얻었습니다.

사용자 스크립트가 시작한 모든 백그라운드 프로세스가 완료 될 때까지 대기하기 위해 대기를 사용할 수 있습니다. 대기는 현재 쉘의 하위에서만 작동하므로 별도의 프로세스로 실행하는 대신 스크립트를 소싱해야합니다.

(소스 사용자 스크립트; 대기)

명시 적 서브 쉘에서 스크립트를 소싱하는 것은 새 프로세스의 시작을 충분히 시뮬레이션하는 것입니다. 그렇지 않은 경우 서브 쉘을 백그라운드로 지정하여 새 프로세스를 강제로 시작한 다음 완료 될 때까지 기다릴 수 있습니다.

(소스 사용자 스크립트; 대기) 및 대기

여기 @chepner에 의해 원래의 대답에 대한 링크는 다음과 같습니다 /programming/18663196/how-to-get-list-of-all-child-process-spawned-by-a-script/18663969?noredirect = 1 # 18663969


3
나는 이것에 대해서도 생각했지만 사용자 스크립트가 백그라운드에서 첨자를 시작한 다음 백그라운드에서 다른 스크립트를 시작 하면이 솔루션이 실패합니다 . 그러면 wait명령이 사용자 스크립트 의 자식을 기다리지 만 손자 를 기다리지는 않습니다.
Tim

@Tim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.