특정 조건이 충족될 때까지 프로세스를 다시 시작하는 비동기 while 루프가 있습니다. 이는 다음과 같습니다:
(while [ "$check_condition" -eq 1 ]; do
./async_command
done) &
... # do some stuff
check_condition=0
pkill -9 async_command
보시다시피 check_condition
0으로 변경하고 아직 실행 중인 비동기 프로세스를 종료했습니다. 문제는 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를 통한 제어가 선호되어야 하지만 이를 남용하여 루프에 "이름을 지정"하고 올바른 루프를 중지할 수 있습니다.