쉘 스크립트에서 비동기 while 루프 중지

쉘 스크립트에서 비동기 while 루프 중지

특정 조건이 충족될 때까지 프로세스를 다시 시작하는 비동기 while 루프가 있습니다. 이는 다음과 같습니다:

(while [ "$check_condition" -eq 1 ]; do
    ./async_command
done) &

... # do some stuff

check_condition=0
pkill -9 async_command

보시다시피 check_condition0으로 변경하고 아직 실행 중인 비동기 프로세스를 종료했습니다. 문제는 while 루프가 계속 실행되고 프로세스가 다시 시작된다는 것입니다.

나는 루프가 check_condition시작 후에만 값을 등록하고 어떤 변경 사항도 알아차리지 못할 것이라고 추측합니다.

이 문제를 어떻게 해결할 수 있나요?

답변1

kill $!백그라운드에서 실행 중인 마지막 프로세스를 종료 해야 합니다 . 바라보다Bash 스크립트에서 "$!"는 무엇을 의미합니까?

백그라운드에서 다른 명령을 실행하는 경우 해당 PID를 변수에 저장 $!하고 나중에 해당 ID를 사용하여 필요할 때마다 프로세스를 종료할 수 있습니다.

( while ... done ) & pid=$!

그 다음에

kill $pid

또는 jobs실행 중인 백그라운드 프로세스를 확인하고 해당 ID를 사용하여 종료합니다.

kill %Id

당신은 또한 볼 수 있습니다백그라운드 프로세스를 종료하는 방법은 무엇입니까?

답변2

coproc명명된 루프를 시뮬레이션하는 데 사용됩니다.

명명된 루프에 가장 가까운 것은 bash다음과 같습니다 coproc.

coproc loop1 { while ((1)) ; do echo a >> aout ; sleep 1 ; done ;} 
echo PID of loop1 $loop1_PID
coproc loop2 { while ((1)) ; do echo b >> bout ; sleep 1 ; done ;} 
echo PID of loop2 $loop2_PID
coproc loop3 { while ((1)) ; do echo c >> cout ; sleep 1 ; done ;}
echo PID of loop3 $loop3_PID

sleep 2
kill $loop1_PID
sleep 2
kill $loop2_PID
sleep 2
kill $loop3_PID

coproc NAME simple_command 
#or
coproc NAME { series ; of ; commands ;}

PID는 저장되며 NAME_PID나중에 이를 사용하여 프로세스를 종료할 수 있습니다.


선택하다:가상 파일

@αГsнιι가 제안한 PID를 사용하는 것이 가장 올바른 방법이지만 여기서 또 다른 아이디어는 더미 파일을 만드는 것입니다.

 #!/bin/bash
 dummy="$(mktemp -u -p .)"
 ( while [ ! -e "$dummy" ] ; do ./async_command ; done ) &
 ...
 #condition met
 touch "$dummy"
 ...

또한 이 파일을 조건이 충족되었음을 나타내는 표시기로 사용할 수도 있고, trap정리하려는 경우 파일을 추가할 수도 있습니다. 다시 말하지만, PID를 통한 제어가 선호되어야 하지만 이를 남용하여 루프에 "이름을 지정"하고 올바른 루프를 중지할 수 있습니다.

관련 정보