백그라운드 프로세스가 완료될 때까지 반복(`jobs` 사용)이 스크립트에서 작동하지 않습니다.

백그라운드 프로세스가 완료될 때까지 반복(`jobs` 사용)이 스크립트에서 작동하지 않습니다.

백그라운드 프로세스(스크립트 앞부분에서 시작됨)가 완료될 때까지 반복하려고 합니다. 쉽게 재현할 수 있는 테스트 사례는 다음과 같습니다.

ping -c 10 localhost &>/dev/null &

명령줄에서 반복할 수 있습니다 while [[ -n $(jobs) ]](while $(jobs)은 null이 아님).

$ ping -c 10 localhost &>/dev/null &
[1] 19078
$ while [[ -n $(jobs) ]]; do echo -n .; sleep 1; done
.........[1]+  Done                    ping -c 5 localhost &> /dev/null

그러나 스크립트의 동일한 두 줄은 를 .누를 때까지 s를 계속 인쇄합니다 Ctrl-C.

jobs이상하게 도 루프 내부에서 호출하면 스크립트가 예상대로 종료됩니다.

$ ./background-ping.sh
.[1]+  Running                 ping -c 5 localhost &> /dev/null &
.[1]+  Running                 ping -c 5 localhost &> /dev/null &
.[1]+  Running                 ping -c 5 localhost &> /dev/null &
.[1]+  Running                 ping -c 5 localhost &> /dev/null &
.[1]+  Done                    ping -c 5 localhost &> /dev/null

백그라운드 작업이 완료되었는지 확인하는 다른 방법(예: 확인)이 있다는 것을 알고 있지만 확인이 예상대로 작동하지 않는 /proc이유를 알고 싶습니다 .jobs

답변1

귀하의 문제를 이해한다면 귀하의 두 줄은 스크립트에서 멈추지 않을 것입니다.

그것이 내가 만든 것입니다:

ping -c 5 google.com &>/dev/null &
while [[ -n $(jobs -r) ]]; do echo -n "."; sleep 1; done

jobs -r실행 중인 프로세스를 확인하고 내 스크립트를 호출하면 예상대로 작동하며 ping이 완료되면 스크립트가 중지됩니다.

편집: 스크립트에서 상위 프로세스는 실행 중인 프로세스로 알려져 있으므로 jobs계속 실행 중인 프로세스가 있다고 생각하는 것 같습니다. 그건 가설이에요

그게 답인가요? (아니면 무슨 말인지 정말 이해가 안 될 수도 있고, 제 영어 실력이 문제일 수도 있습니다...)

답변2

이와 같은 문제가 발생할 때마다 항상 변수를 인쇄하여 무슨 일이 일어나고 있는지 이해해야 합니다. 이 경우 jobs완료된 작업도 반환됩니다. 이것을 실행하면:

ping -c 5 localhost &>/dev/null &
while [[ -n $(jobs | tee -a temp) ]]; do
    echo -n .; 
    sleep 1; 
done

다음 출력이 표시됩니다 temp.

[1]+  Running                 ping -c 5 localhost &> /dev/null &
[1]+  Running                 ping -c 5 localhost &> /dev/null &
[1]+  Running                 ping -c 5 localhost &> /dev/null &
[1]+  Running                 ping -c 5 localhost &> /dev/null &
[1]+  Done                    ping -c 5 localhost &> /dev/null
[1]+  Done                    ping -c 5 localhost &> /dev/null
[1]+  Done                    ping -c 5 localhost &> /dev/null
[1]+  Done                    ping -c 5 localhost &> /dev/null
[1]+  Done                    ping -c 5 localhost &> /dev/null
[...]

따라서 jobs여기의 출력은 결코 비어 있지 않습니다. 작업이 완료되어도 jobs여전히 Done메시지를 반환합니다. 이것이 Metal3d의 솔루션이 효과가 jobs -r있었던 이유입니다.

더 혼란스러운 것은 jobs루프 내에서 실행하면 올바르게 작동하는 이유입니다. 대답은 별도의 하위 쉘에서 while [[ -n $(jobs) ]]실행된다는 사실과 관련이 있지만 jobs자세한 내용은 잘 모르겠습니다. 나는 가지고있다질문을 게시했습니다관심 있는 사람이 있다면 U&L에서 이에 대해 알아보세요.

답변3

wait백그라운드 작업이 중지될 때까지 기다리는 명령을 사용할 수 있습니다.

예:

$ ping -c 10 localhost &>/dev/null &
[29787]
$ wait
[1]+  Done ping -c 10 localhost &>/dev/null

wait 명령이 차단되고 ping완료되면 프롬프트가 해제되고 메시지가 인쇄됩니다.

is를 여러 명령과 함께 사용할 수 있습니다.

$ ping -c 5 localhost &>/dev/null & ping -c 5 facebook.com  &>/dev/null &
[1] 29867
[2] 29868
$ wait
[1]-  Done                    ping -c 5 localhost &>/dev/null
[2]+  Done                    ping -c 5 facebook.com &>/dev/null

관련 정보