如果我们有以下命令:
# 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
s 打印了大约 14556 行,然后A
s 打印了 76367 行,等等。yes
应该写入包含完整行的块,因此混合的行应该是由于两个进程覆盖了每个进程其他。
请注意,如果您使用附加重定向,>> test.txt
则所有写入都将转到文件末尾(在写入时,忽略各个写入指针位置),并且不会发生覆盖,您将获得所有内容输入的数据只是交错(随机)。