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
包含 xxx
和 y
包含 yyy
:
命令未完成。 x
保持不变(如您所料)并且 y
以大量 xxx
.
行结尾
这就是我合理化行为的方式:
>
重定向运算符做的第一件事是截断 y
准备接收重定向数据。因此没有 yyy
字节以 y
.
结束
由于重定向进程开始写入数据时y
为空,cat x y
(初始)的输出只是xxx
。
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
的实际执行之前-- 因此,在上述所有内容之前。
因此,我们准确地看到了您提出的内容:只有一行 xxx
s 可供读取 until cat 执行写入,此时附加内容立即可供读取,因此循环继续。
我目前正在阅读 Kernighan 和 Pike 的优秀著作 The UNIX Programming Environment。他们给出的一个有趣的例子(练习 3-7)是命令
cat x y > y
我尝试了 运行 这个命令,文件的初始内容是 x
包含 xxx
和 y
包含 yyy
:
命令未完成。 x
保持不变(如您所料)并且 y
以大量 xxx
.
这就是我合理化行为的方式:
>
重定向运算符做的第一件事是截断y
准备接收重定向数据。因此没有yyy
字节以y
. 结束
由于重定向进程开始写入数据时
y
为空,cat x y
(初始)的输出只是xxx
。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
的实际执行之前-- 因此,在上述所有内容之前。
因此,我们准确地看到了您提出的内容:只有一行 xxx
s 可供读取 until cat 执行写入,此时附加内容立即可供读取,因此循环继续。