다음 명령이 있는 경우:
# first
cat /dev/random | base64 > test.txt &
# second
cat /dev/random | base64 > test.txt &
첫 번째 명령을 실행한 다음 두 번째 명령을 실행하고 kill
두 명령을 모두 중지하면(사용) 해당 명령은 어디에서 왔습니까 test.txt
? 첫 번째 명령인가요, 두 번째 명령인가요, 아니면 둘 다인가요?
다음 테스트를 실행했는데 위의 내용 중 아무 것도 아닌 것 같나요? 이유는 모르겠습니다.
$ cat /dev/random | base64 | tee 1.txt > test.txt &
$ cat /dev/random | base64 | tee 2.txt > test.txt &
# $ kill task1_id task2_id
$ ll -h
total 1.8G
drwxrwxrwx 1 user user 4.0K Dec 9 16:55 ./
drwxrwxrwx 1 user user 4.0K Dec 9 16:51 ../
-rwxrwxrwx 1 user user 627M Dec 9 16:55 1.txt*
-rwxrwxrwx 1 user user 585M Dec 9 16:55 2.txt*
-rwxrwxrwx 1 user user 627M Dec 9 16:55 test.txt*
$ md5sum *.txt
f83c833de426f22152e91f5c31bb0a7c 1.txt
e7535f298cc935c81064bfaf26dcd244 2.txt
35e7830de4decc1572b8b16d54170851 test.txt
답변1
정말 엉망이군요. 이런 식으로는 의미 있는 어떤 것도 얻지 못할 것입니다.
먼저 프로세스 중 하나가 파일을 열고 잘라낸 다음 파일에 무언가를 씁니다. 쓰기 포인터는 끝난 위치에 남아 있습니다.
그런 다음 두 번째 프로세스는 파일을 열고 자르고(첫 번째 프로세스가 지금까지 작성한 모든 항목을 제거하지만 이는 중요하지 않음) 파일에 내용을 씁니다. 쓰기 포인터는 끝난 위치에 남아 있습니다.
그런 다음 프로세스는 가능한 한 많이 씁니다.해당 시점의 각 쓰기 포인터 위치. 그러나 그 순서는 운영 체제의 스케줄링 결정에 따라 달라집니다. 즉, 본질적으로 무작위입니다. 동기화 상태가 유지된다는 보장이 없으므로 서로 다른 시점에 부분적으로 서로 덮어쓸 수 있습니다. 결과는 두 데이터 세트의 혼합일 수 있습니다.
간단한 테스트 yes
:
$ yes AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA > test.txt & \
yes BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB > test.txt & \
sleep .3; kill %1 %2
$ uniq -c test.txt
14556 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
1 BBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
76367 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1 AAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
1033303 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
1 AAAAA
1532199 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
uniq -c
반복되는 줄 수를 세어 보면 여기서는 B
약 14556줄이 인쇄된 다음 A
76367줄이 인쇄되는 등의 방식으로 표시됩니다. yes
완전한 행을 포함하는 블록을 작성해야 하므로 두 프로세스가 서로 덮어쓰기 때문에 혼합된 행이 발생해야 합니다.
추가 리디렉션을 사용하는 경우 >> test.txt
모든 쓰기는 파일 끝으로 이동하고(쓰기 동안 개별 쓰기 포인터 위치는 무시됨) 덮어쓰기가 발생하지 않으며 모든 입력 데이터가 인터리브(임의)됩니다.