【问题标题】:Unix/Linux cat x y > y : is my understanding of the processing correct?Unix/Linux cat x y > y :我对处理的理解正确吗?
【发布时间】:2015-10-23 20:44:32
【问题描述】:

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

cat x y > y

我尝试运行此命令,文件的初始内容为 x 包含 xxxy 包含 yyy

命令未完成。 x 保持不变(如您所料),y 以大量 xxx 行结束。

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

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

  2. 由于重定向过程开始写入数据时y 为空,所以cat x y(最初)的输出只是xxx

  3. cat 在到达 y 的 EOF 之前不会停止写入。但它永远不会达到 EOF,因为随着每个写操作的完成,它会将 EOF 推到更远的当前读/写指针之外?所以cat 会无限期地将y 附加到自身。

如果有人可以对这种行为提供更清晰(并且更少手摇)的解释,或者如果这完全是垃圾,请纠正我,那将不胜感激。

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

非常感谢,

MB

【问题讨论】:

  • 你覆盖了文件 y 的内容。
  • 您使用的是哪个版本的cat? gnu cat 8.21 将 x 的内容转储到 y,然后以 cat: y: input file is output file 中止
  • 使用猫 8.23。当您在第 2 点中声明时,y 为空,它会被 x 的内容覆盖,从而产生消息 `$ cat x y > y cat: y: input file is output file'
  • @Marc B - 我正在使用 OSX 猫。 @Charles Duffy - 我会尝试了解 strace - 听起来很有用 :-) ... 调查一下 ...呃哦,strace 不适用于 OSX ...我'将不得不研究一个等价物。感谢您的建议。
  • 看看你有truss还是dtruss

标签: linux unix cat io-redirection


【解决方案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() 之后生成子进程,然后执行的猫但在cat 的实际执行之前 - 因此,在上述所有之前。

因此,我们确切地看到了您的假设:只有一行 xxxs 可供读取直到 cat 执行写入,此时其他内容立即可供读取,所以循环继续。

【讨论】:

    猜你喜欢
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2021-07-24
    • 1970-01-01
    • 2016-02-16
    • 2021-09-01
    • 1970-01-01
    相关资源
    最近更新 更多