Unix/Linux cat x y > y : 我对处理的理解正确吗?

Unix/Linux cat x y > y : is my understanding of the processing correct?

我目前正在阅读 Kernighan 和 Pike 的优秀著作 The UNIX Programming Environment。他们给出的一个有趣的例子(练习 3-7)是命令

cat x y > y

我尝试了 运行 这个命令,文件的初始内容是 x 包含 xxxy 包含 yyy:

命令未完成。 x 保持不变(如您所料)并且 y 以大量 xxx.

行结尾

这就是我合理化行为的方式:

  1. > 重定向运算符做的第一件事是截断 y 准备接收重定向数据。因此没有 yyy 字节以 y.

  2. 结束
  3. 由于重定向进程开始写入数据时y为空,cat x y(初始)的输出只是xxx

  4. cat 直到到达 y 的 EOF 才会停止写入。但它永远不会到达 EOF,因为随着每个写操作的完成,它会将 EOF 进一步推过当前的 read/write 指针?所以 cat 会无限期地将 y 附加到自身。

如果有人能对这种行为提供更清晰(且更简洁)的解释,或者如果这完全是垃圾,请纠正我,我们将不胜感激。

此外,我确信我曾经在网上找到了一套解决本书中问题的有效解决方案,但我现在找不到了。如果有人能指出我这样的事情,那就太好了。

非常感谢,

MB

是的,你现有的理解是正确的。

查看实际系统调用(来自 strace busybox cat x y >y,以避免 GNU 版本尝试检测和终止此类循环):

open("x", O_RDONLY)                     = 3
read(3, "xxx\n", 4096)                  = 4
write(1, "xxx\n", 4)                    = 4
read(3, "", 4096)                       = 0
close(3)                                = 0
open("y", O_RDONLY)                     = 3
read(3, "xxx\n", 4096)                  = 4
write(1, "xxx\n", 4)                    = 4
read(3, "xxx\n", 4096)                  = 4
write(1, "xxx\n", 4)                    = 4

...最后两行无限重复。

未显示的是外部 shell 的 open("y", O_WRONLY|O_CREAT|O_TRUNC, 0666),在 fork() 之后完成以生成子进程,然后执行 cat 但在 cat 的实际执行之前-- 因此,在上述所有内容之前。

因此,我们准确地看到了您提出的内容:只有一行 xxxs 可供读取 until cat 执行写入,此时附加内容立即可供读取,因此循环继续。