我想知道如何正确理解以下内容:
在我看来,我首先将STDOUT
重定向到文件,然后,我将STDERR
重定向到STDOUT
。然而,这似乎恰恰相反:
$ perl -e "print STDERR 'stderr'; print STDOUT 'stdout'" >file 2>&1
$ cat file
stderrstdout
现在,我假设我首先将STDERR
重定向到STDOUT
,因此STDOUT
和STDERR
都与STDOUT
相关联,然后我重定向{{ 1}}提交。
STDOUT
我似乎误解了我应该怎么读这个。有人可以向我解释一下吗?
答案 0 :(得分:1)
ScrollView
并没有将stderr指向stdout。它不以任何方式将两个流合并为一个。没有别名或还原。
相反,2>&1
将stderr指向stdout当前指向的位置,而不是stdout本身。之后,您可以自由地更改stdout指向的位置,而不会影响stderr。
你可以这样想2>&1
:
> file 2>&1
所以两个输出都到达了文件,就像你看到的那样。
同样,stdout=terminal stderr=terminal # inherited default
stdout=file # > file
stderr=$stdout # 2>&1
echo "stdout=$stdout" # result: stdout=file
echo "stderr=$stderr" # result: stderr=file
将是:
2>&1 > file
所以stderr再次进入终端,就像你一直看到的那样。
实际实现基本上就是这样,但使用stdout=terminal stderr=terminal # inherited default
stderr=$stdout # 2>&1
stdout=file # > file
echo "stdout=$stdout" # result: stdout=file
echo "stderr=$stderr" # result: stderr=terminal
而不是分配给fd和dup2()
而不是分配给open()
答案 1 :(得分:0)
在第一个示例中,bash在调用perl之前设置重定向。重定向按照您的描述进行排列:标准输出转到文件,标准错误转到同一文件。然后perl运行,首先输出错误然后输出。由于错误和输出指向同一文件,因此文件将按照打印的顺序填写 。
在第二个示例中,2>&1
将标准错误重定向到默认标准输出的位置(控制台)。然后关闭标准输出默认值并重定向到文件(通过>file
)。这里重要的一点是,当您关闭重定向时,所有别名重定向也会关闭并恢复到之前的位置。在这种情况下,当标准输出转到新文件时,标准错误将恢复为控制台。
我使用语言来描述可见效果,而不是讨论bash如何在幕后实现这一点。