我有一个文件test.txt
,没有名为的文件test
。当我尝试
ls test test.txt > new 2>new
new
由于>>
没有使用,我期望被覆盖。但是在输出文件中,我同时添加了两个内容。为什么会这样呢?
TL; DR bash
将打开并截断所有涉及的文件,然后再将任何内容写入其中。stdout
并且stderr
都被发送到,new
因为开始打印bash
时已经将文件截断了两次ls
。
这就是bash
准备/处理I / O重定向的方式。当您要求将命令重定向(>
)到文件时,bash
基本上会打开该文件,并在必要时创建它。如果该文件已经存在,它将被截断。open
在您的情况下,这是通过系统调用和一些标志来完成的:
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
O_CREAT
如果文件不存在,则创建该文件;如果文件不存在,则将其O_TRUNC
截断。此open
系统调用是bash
的初始化的一部分,这意味着当您使用多个重定向操作时(例如在...中)
$ ls test test.txt > new 2>new
...bash
首先打开所有相关文件。因此,在运行之前ls
,它将打开new
两次,并带有相同的标志:
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
这意味着基本上,在运行命令时,bash
将按以下顺序执行以下操作:
new
为标准输出,必要时创建/截断文件。new
以标准错误打开,请在必要时创建/截断文件。ls
:这会将内容写入new
。如您所见,在启动之前会bash
截断所有涉及的文件。这意味着,使用时,基本上将其“截断”两次,然后将输出重定向到该对象。您期望的行为将需要独立捕获的stdout和stderr,并在编写之前将它们一个接一个地打开。基本上:ls
... >new 2>new
new
bash
ls
ls
。stdout
,请打开new
,截断并写入。stderr
,new
再次打开,截断并写入。但是,消息可能会交织在一起:重定向的程序很可能会先向写入内容stdout
,然后再向写入其他内容,然后stderr
再返回stdout
...管理所有这些内容是可怕的(这可能会导致不良后果(未定义?)。行为...)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句