쉘 스크립트는 백그라운드 명령을 기다립니다


12

스크립트를 작성하고 있지만 할 수없는 방법이 있습니다 ...

백그라운드 "command1 &"에서 명령을 작성한 다음 스크립트 어딘가에서 command2를 수행하기 전에 명령이 완료 될 때까지 기다려야합니다. 기본적으로 나는 이것이 필요하다.

참고 : 각 명령은 특정 디렉토리에서 실행됩니다! while 루프가 끝나면 내 command1은 4 개의 디렉토리를 만들었습니다. 각 디렉토리마다 특정 프로세스를 실행하므로 총 실행중인 프로세스는 4입니다.

a=1

while [$a -lt 4 ]

     . command1
   #Generates 1 Process  

     a= `export $a +1`
done

   #Wait until the 4 process end and then run the command2 

    . command2

waitpid 프로세스 번호 가있는 명령 에 대해 보았지만 작동하지 않았습니다.


당신은 제어 command1합니까? 4 개의 프로세스의 PID를 반환하도록 수정할 수 있습니까?
terdon

예! 나는 이미 그것을 가지고 :)
Joao Macau

이에 따라 답변을 업데이트했습니다. 그것이 당신의 기대와 일치하는지 말해주십시오.
Laurent C.

이 Q는 unix.stackexchange.com/questions/100801/… 과 관련이 있습니다. 유일한 차이점은 백그라운드 프로세스에서 PID를 가져와야한다는 것입니다. $!변수를 사용하여 이것을 얻을 수 wait있으며 내가 보여준 것처럼 명령에 전달할 수 있습니다. $!마지막 백그라운드 PID를 $$포함하고 마지막 프로세스 실행 PID 를 포함합니다.
slm

3
이제 스크립트가 전혀 이해가되지 않습니다. 구문 오류와 이상이 있습니다. 실제 스크립트 를 보여 주 시겠습니까? 명령을 왜 소싱합니까? 왜 그냥 실행하지 않습니까?
terdon

답변:


22

명령 wait PID을 사용하여 프로세스가 끝날 때까지 기다릴 수 있습니다 .

마지막 명령의 PID를 검색 할 수도 있습니다. $!

귀하의 경우 다음과 같이 작동합니다.

command1 & #run command1 in background
PID=$! #catch the last PID, here from command1
command2 #run command2 while command1 is running in background
wait $PID #wait for command1, in background, to end
command3 #execute once command1 ended

편집 후 여러 PID가 있고 알고 있으므로 다음과 같이 할 수 있습니다.

command1 & #run command1 in background
PID1=xxxxx
PID2=yyyyy
PID3=xxyyy
PID4=yyxxx
command2 #run command2 while command1 is running in background
wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end
command3 #execute once command1 ended

편집 한 후 생성 된 PID (xxxxx, yyyyy, xxyyy, yyxxx)를 알고 있으면 대기 할 PID 목록과 함께 wait도 사용할 수 있습니다 (man 참조). 당신이 그것들을 모른다면, 아마도 그것들을 command1에 모을 수있을 것입니다 (command1은 무엇입니까? 자신의 스크립트입니까?)
Laurent C.

처음에 올바르게 그룹화되도록하는 것이 가장 좋습니다. 어떻게 할 수 있는지에 대한 아이디어는 내 대답을 참조하십시오.
mikeserv

4

가장 깨끗한 방법 comamnd1은 시작된 프로세스의 PID를 반환하고 wait@ LaurentC 's answer에서 제안한대로 각 프로세스에서 PID를 사용 하는 입니다.

다른 접근 방식은 다음과 같습니다.

## Create a log file
logfile=$(mktemp)

## Run your command and have it print into the log file
## when it's finsihed.
command1 && echo 1 > $logfile &

## Wait for it. The [ ! -s $logfile ] is true while the file is 
## empty. The -s means "check that the file is NOT empty" so ! -s
## means the opposite, check that the file IS empty. So, since
## the command above will print into the file as soon as it's finished
## this loop will run as long as  the previous command si runnning.
while [ ! -s $logfile ]; do sleep 1; done

## continue
command2

죄송하지만 여전히 작동하지 않습니다. 질문을 다시 한 번 개선하겠습니다!
Joao Macau

0

다음 방법을 사용하는 경우 while 루프 후 특별한 "모든 프로세스 대기"가 필요하지 않을 수 있습니다. 루프는 순환이 command1시작되기 전에 전류 가 완료 될 때까지 기다립니다 . 조언과 마찬가지로주의해서 사용하십시오. 내가 한 유일한 것은 & wait $!귀하의 끝에 추가 되었습니다 command1.

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.