Bash에서 경쟁 조건이 발생합니까?

Bash에서 경쟁 조건이 발생합니까?

명령의 출력을 이전에 동일한 명령을 실행한 결과와 비교하는 스크립트가 있는데 작동합니다.최대하지만 때로는 예상대로 작동하지 않을 때도 있습니다.

테스트 라인에서 문제를 재현할 수 있었습니다. 나는 이것을 두 개의 별도 파일을 비교하여 쉽게 나눌 수 있다는 것을 알고 있으며 문제는 사라질 것입니다. 그러나 여기서 실제로 무슨 일이 일어나고 있는지, 그리고 내가 달성하려는 것을 달성할 수 있는 방법이 있는지 이해하고 싶습니다. 그것.

다음은 여러 번 실행된 명령의 출력입니다. 한 경우에 "test"가 에코되는 것을 볼 수 있지만 대부분의 경우 예상대로 작동합니다.

root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)
root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)
root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)
root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)
root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)
test
root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)
root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)
root@dev:~# comm -13 /tmp/test <(echo '"test"' | cut -d'"' -f2 | sort -u | tee /tmp/test)

나는 달리고 Ubuntu 10.04있고bash 4.1-2ubuntu3.5coreutils 7.4-2ubuntu3

답변1

예, 이것은 경쟁 조건입니다.

문제는 쉘이 파이프의 모든 프로세스를 동시에 시작하고 tee가 시작 시 출력 파일을 자르는 것입니다. tee가 comm보다 빠르면 comm용 파일은 비어 있고 그렇지 않으면 비어 있습니다.

여러 번 실행하는 경우(아마도 루프에서) 파이프라인 동작을 볼 수 있습니다.

date '+first:  %T'|(cat>&2;sleep 5)|date '+second: %T'

답변2

두 번 나타나는 "테스트"가 무엇인지 명확하지 않기 때문에 귀하의 라인은 나를 약간 혼란스럽게 합니다. -그래서 나는 당신의 껍질도 혼란스러워한다는 것을 정말로 이해합니다. ;)

내가 올바르게 이해했다면 첫 번째 "/tmp/test"는 명령의 이전 출력에 해당하고 두 번째는 새 출력에 해당해야 합니다.

stdin에 새 출력이 포함된다는 것을 확신할 수 있지만 파일의 내용은 정의되지 않았습니다. comm파일을 읽을 때 아직 시작되지 않았을 수 있습니다 tee. 이 경우 마지막 실행의 이전 "테스트" 행이 계속 포함됩니다. 아니면 tee이미 완료되었을 수도 있습니다. 이 경우 현재 실행 중인 "테스트" 행이 포함됩니다. 또는 tee방금 시작하여 파일이 지워지고 새 콘텐츠가 곧 작성될 예정입니다. 이런 일이 발생하면 표준 입력의 "테스트"를 빈 파일과 비교하여 출력을 볼 수 있습니다.

두 개의 서로 다른 출력을 비교하려고 합니다. 두 개의 서로 다른 파일 없이는 이 작업을 수행할 수 있는 방법이 없습니다. 두 개의 서로 다른(적절한 이름의) 파일을 사용하면 행을 더 쉽게 읽을 수 있고 처음에 발생하는 혼란을 해결할 수 있습니다. ;)

관련 정보