【问题标题】:Why reading and writing the same file through I/O redirection results in an empty file in Unix?为什么在 Unix 中通过 I/O 重定向读写同一个文件会导致一个空文件?
【发布时间】:2009-12-13 09:17:57
【问题描述】:

如果我将命令的输出重定向到它读取的同一文件,则其内容将被删除。

sed 's/abd/def/g' a.txt > a.txt

谁能解释一下原因?

【问题讨论】:

    标签: shell unix io-redirection


    【解决方案1】:

    重定向所做的第一件事是打开文件进行写入,从而清除所有现有内容。 sed 然后尝试读取您刚刚创建的这个空文件,并且什么也不做。然后关闭文件,不包含任何内容。

    【讨论】:

      【解决方案2】:

      重定向操作<>等由shell处理。当您向 shell 发出包含重定向的命令时,shell 将首先打开该文件。在> 的情况下,文件将被打开以进行写入,这意味着它被截断为零大小。打开重定向文件后,shell 启动一个新进程,将其标准输入、输出和错误绑定到任何可能的重定向文件,然后才执行您提供的命令。因此,当您的示例中的 sed 命令开始执行时,a.txt 已被 shell 截断。

      顺便说一句,这也是您不能直接对sudo 使用重定向的原因,因为需要权限才能打开重定向文件的是shell,而不是正在执行的命令。

      【讨论】:

        【解决方案3】:

        您需要使用-i 选项来编辑文件:

        sed -i .bck 's/abd/def/g' a.txt

        编辑:正如尼尔所说,重定向首先打开文件进行写入,从而清除它。

        EDIT2:对某些读者来说可能会很有趣

        在 OSX 上,如果您想使用带有空扩展名的 -i 来防止创建备份文件,您还需要使用 -eswitch 否则无法正确解析参数:

        sed -i -e 's/abc/def/g' a.txt

        【讨论】:

        • 错了,提问者指出一个文件被传递来读取。另一个答案有正确的原因。
        【解决方案4】:

        stdout 和 stderr 将首先准备好,然后是 stdin,然后执行命令。所以 a.txt 首先对于标准输出是明确的,然后当命令执行时找不到任何内容。 尝试 sed -i 's/abd/def/g' a.txt 或者 sed 's/abd/def/g' a.txt 1 a.txt

        【讨论】:

          猜你喜欢
          • 2017-03-04
          • 1970-01-01
          • 2023-04-05
          • 1970-01-01
          • 2018-04-22
          • 2015-08-30
          • 1970-01-01
          • 2015-10-19
          • 2017-05-09
          相关资源
          最近更新 更多