如果两个管道同时重定向到一个文件会发生什么

如果两个管道同时重定向到一个文件会发生什么

如果我们有以下命令:

# 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计算重复的行数,因此我们可以看到,在这里,Bs 打印了大约 14556 行,然后As 打印了 76367 行,等等。yes应该写入包含完整行的块,因此混合的行应该是由于两个进程覆盖了每个进程其他。

请注意,如果您使用附加重定向,>> test.txt则所有写入都将转到文件末尾(在写入时,忽略各个写入指针位置),并且不会发生覆盖,您将获得所有内容输入的数据只是交错(随机)。

相关内容