我目前正在使用Kernighan和Pike的优秀书籍 UNIX编程环境。他们给出的一个有趣的例子(练习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推到当前的读/写指针之外?因此cat
会无限期地将y
附加到自身。
如果有人能够对这种行为提供更清晰(并且更少手写)的解释,或者如果这是完全垃圾,请纠正我,这将非常感激。
另外,我确信在某一点上我在网上找到了一套解决问题的解决方案,但我现在无法找到它们。如果有人能指出我这样的话,那就太棒了。
非常感谢,
MB
答案 0 :(得分:1)
是的,您现有的理解是正确的。
查看实际的系统调用(来自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
......最后两行无限重复。
外壳的open("y", O_WRONLY|O_CREAT|O_TRUNC, 0666)
未显示,在fork()
生成子进程之后完成,然后exec的cat但在cat
实际执行之前 - 因此,在所有之前以上。
因此,我们确切地看到您所提出的内容:只有一行xxx
可用于读取,直到 cat执行写入,此时其他内容可立即读取,所以循环继续。