多个进程使用 > 重定向到同一个文件

多个进程使用 > 重定向到同一个文件

这不是一个“如何追加而不覆盖”的问题。我不是在寻找组合两个命令的输出的文件。这只是我犯的一个错误,我想了解为什么系统会这样做

我使用一个命令(在远程 ssh 命令行上)需要很长时间才能完成并将数据(每隔几秒逐行)输出到 stdout,因此我将其重定向到一个文件:

command > file.out &

有时远程会话会断开连接,但命令会继续在后台运行。我不知道这一点,所以我再次运行相同的命令,在第一个完成之前

command > file.out &

当两个进程完成后,我希望(在阅读此站点上的一些答案之后)有一个文件,其中两个命令的行都弄乱了,但输出文件仅包含两次执行之一的输出。

为什么该文件的两个输出没有交织在一起(正如评论中警告的那样)这里)?最终文件属于 2 个输出中的哪一个?

编辑:

删除了其中一个问题(为什么输出文件没有锁定写入?),如其解释这里

答案1

当您使用重定向打开文件进行写入时>,该文件是被截断的,即完全清空。然而却是不是删除并重新创建。

如果一个命令首先截断文件,然后向其中写入一些内容,并且如果另一个命令随后执行相同操作,则第一个命令在文件中的位置将不会更改。这意味着您有两个命令在两个独立的位置写入同一个文件,一个可能会覆盖另一个的输出,取决于写入顺序和写入的数据量

所以,是的,文件中的数据很可能是两个程序输出的交织在一起的混乱,但这将取决于写入文件的顺序,以及写入的数据量和截断的时间。文件。

以下是交织来自两个命令的数据的示例:

#!/bin/sh

( { echo hello; sleep 2; echo world; } | cat >file ) &
sleep 1
echo 123 >file &

wait

这是此脚本中发生的情况:

  1. 第一个命令打开文件进行写入并截断它。它会写入hello\n它。
  2. 一秒钟后,第二个命令截断文件并写入123\n。此时,第一个命令的文件指针仍然指向文件的某个偏移量。
  3. 第一个命令继续写入world\n文件。

结果是一个中间有一段 nul 字符的文件:

$ hexdump -C file
00000000  31 32 33 0a 00 00 77 6f  72 6c 64 0a              |123...world.|
0000000c

nul(00在上面的输出中)来自这样一个事实:第一个命令的文件指针没有被第二个命令的文件截断重置,因此创建了一个“洞”。第二个命令仅写入,123\n但如果写入更多数据,则会覆盖 nul:

$ hexdump -C file
00000000  31 32 33 34 35 36 77 6f  72 6c 64 0a              |123456world.|
0000000c

这里我已经创建了第二个命令echo 1234567890,但1234567文件中只留下了。这是因为world\n在第二个命令完成写入后,第一个命令继续在其文件指针所在的位置写入。

相关内容