루프는 백그라운드 서브셸의 변수 변경 사항을 무시합니다.

루프는 백그라운드 서브셸의 변수 변경 사항을 무시합니다.

루프가 포함된 스크립트를 작성했습니다 until. 루프는 true부울 변수가 루프 외부에서 설정될 때까지 실행되어야 합니다. 불행히도 루프는 변수가 true로 설정된 것을 무시하고 계속 실행됩니다. 이 문제를 일으키는 줄은 다음과 같습니다.

boolean=false
{ sleep 5 && boolean=true && echo "boolean is true now" ; } &
{ until [ "$boolean" = true ] ; do sleep 1 && echo $boolean ; done ; } &&
echo "boolean is true now: $boolean"

생성된 출력은 다음과 같습니다.

false
false
false
false
boolean is true now
false
false
false
...

boolean로 설정된 경우 루프를 종료하려면 어떻게 해야 합니까 true?

답변1

신호는 전경 쉘과 배경 쉘 사이의 통신에 사용될 수 있습니다.

#!/bin/bash

# global variable for foreground shell
boolean=false

# register a signal handler for SIGUSR1
trap handler USR1

# the handler sets the global variable
handler() { boolean=true; }

echo "before: $boolean"

# Here, "$$" is the pid of the foreground shell
{ sleep 5; kill -USR1 $$; echo "finished background process"; } &

# busy waiting
until $boolean; do 
    echo "waiting..."
    sleep 1
done

echo "after: $boolean"

산출

before: false
waiting...
waiting...
waiting...
waiting...
waiting...
finished background process
after: true

답변2

역할은 &백그라운드 프로세스를 수행합니다. 백그라운드 프로세스는 서브셸에서 비동기적으로 실행됩니다. 변수는 상위 쉘에서 하위 쉘로 전달될 수 있지만 그 반대의 경우는 불가능합니다. 그러나 서브셸에 설정된 값이 정말로 필요한 경우 해결 방법이 있습니다.

boolean=$(mktemp) && echo "false" >$boolean
{ sleep 5 && echo true >$boolean && echo "boolean is true now" ; } &
{ until [ "$(cat $boolean)" = "true" ] ; do sleep 1 && cat $boolean ; done ; } &&
echo "boolean is true now: $(cat $boolean)"

이는 내용이 부울 값인 임시 파일을 생성합니다. untiltrue 가 포함될 때까지 루프에서 파일을 확인합니다 .

알아채다:

(가능한 경우) 스크립트에서 다음을 수행하는 것이 좋습니다.

{ sleep 5 && echo "background process done" ; } &
wait
echo "continue in foregound."

wait백그라운드 프로세스가 완료될 때까지 기다립니다.

답변3

boolean두 번째 줄에서 true로 설정된 부울 값이 until명령문에서 테스트하는 부울 값과 동일 하다고 잘못 생각합니다 . 이것은 사실이 아닙니다. 새 프로세스를 시작하고 백그라운드에서 새 셸을 사용하면 boolean(테스트한 셸) 할당되지 않습니다.

관련 정보