동일한 파일에 에코되는 두 개의 스크립트가 병렬로 실행 중입니다. 한 스크립트는 +++++++++++++++
파일을 에코하고 다른 스크립트는 ===========
파일을 에코합니다.
아래는 첫 번째 스크립트입니다.
#!/bin/bash
while [ 1==1 ];
do
echo "+++++++++++++++" >> log.txt
# commands
done
두 번째 스크립트는 다음과 같습니다.
#!/bin/bash
while [ 1==1 ];
do
echo "===========" >> log.txt
# commands
done
log.txt 파일은 약 1,400,000줄을 인쇄하는데, 단 한 줄도 ++== 같은 혼동되는 대문자가 없습니까?
리눅스가 이러한 혼란을 막을 수 있을까요? 그렇다면, 어떻게 그리고 왜?
답변1
간단히 말해서 이 echo
명령은 write
원자성 시스템 호출을 트리거합니다.
write
지정된 모든 바이트가 기록된다는 보장은 없지만 이 경우(데이터가 적음)에는 기록됩니다 .
그런 다음 이론적으로 바이트 write(fd, buffer, n)
보다 적게 쓰고 n
프로그램이 바이트를 쓸 수 있도록 쓰여진 실제 바이트 수를 반환하는 것이 가능합니다 buffer+n
.
파이프에는 무제한 용량이 없기 때문에 파이프에서 이런 일이 발생할 수 있습니다.
~에서write(2)
O_APPEND(2)를 사용하여 파일을 연 경우 파일 오프셋은 쓰기 전에 먼저 파일 끝으로 설정됩니다. 파일 오프셋 조정 및 쓰기 작업은 원자적 단계로 수행됩니다.
POSIX.1에 따르면 count가 SSIZE_MAX보다 크면 결과는 구현에 따라 정의됩니다. Linux의 상한에 대한 설명을 참조하세요.
답변2
다음 한도를 시도해 볼 수 있습니다.
#!/bin/bash
outer() {
rm log.txt
inner() {
a=$(perl -e 'print "'$1'"x'$2'')
while [ 1==1 ];
do
echo $a >> log.txt
# commands
done
}
export -f inner
timeout 5 bash -c "inner '-' $1" &
timeout 5 bash -c "inner '+' $1" &
wait
sort -u log.txt
}
replace_repeats() {
# Replace
# ---
# with
# -3
perl -pe 's/((.)\2+)/"$2".length$1/e'
}
# This is OK
outer 10 | replace_repeats
outer 100 | replace_repeats
outer 1000 | replace_repeats
outer 4095 | replace_repeats
# This breaks.
# It should give:
# +4096
# -4096
outer 4096 | replace_repeats