Shell 什么';“command>;输出`和`命令2>&;1>;输出`?
我对将stdout重定向到一个文件,然后将stderr重定向到stdout的常用方法有些熟悉。 如果我运行一个命令,比如Shell 什么';“command>;输出`和`命令2>&;1>;输出`?,shell,operating-system,Shell,Operating System,我对将stdout重定向到一个文件,然后将stderr重定向到stdout的常用方法有些熟悉。 如果我运行一个命令,比如ls>output.txt 2>&1,我猜在引擎盖下,shell正在执行类似以下c代码的操作: close(1) open("output.txt") // assigned to fd 1 close(2) dup2(1, 2) 由于fd 1已被output.txt替换,因此打印到stderr的任何内容都将重定向到output.txt。 但是,如果我运行ls 2>&1>ou
ls>output.txt 2>&1
,我猜在引擎盖下,shell正在执行类似以下c代码的操作:
close(1)
open("output.txt") // assigned to fd 1
close(2)
dup2(1, 2)
由于fd 1已被output.txt替换,因此打印到stderr的任何内容都将重定向到output.txt。
但是,如果我运行ls 2>&1>output.txt
,我猜会发生以下情况:
close(2)
dup2(1, 2)
close(1)
open("output.txt")
但是,由于shell默认同时打印stdout和stderr,因此
ls 2>&1 output.txt
和ls>output.txt
之间有什么区别吗?在这两种情况下,stdout将被重定向到output.txt,而stderr将被打印到控制台。使用ls>output.txt
,来自ls
的stderr
将转到从调用进程继承的stderr
。相反,使用ls 2>&1>output.txt
,ls
的stderr
被发送到调用进程的stdout
让我们用一个示例脚本来尝试这一点,该脚本向stdout
和stderr
中的每一个打印一行输出:
$ cat pr.sh
#!/bin/sh
echo "to stdout"
echo "to stderr" 1>&2
$ sh pr.sh >/dev/null
to stderr
$ sh pr.sh 2>/dev/null
to stdout
现在,如果我们在第一个命令行中插入“2>&1”,则没有什么不同:
$ sh pr.sh 2>&1 >/dev/null
to stderr
但是现在让我们在继承的stdout
将要去控制台以外的地方的上下文中运行这两个:
$ (sh pr.sh 2>&1 >/dev/null) >/dev/null
$ (sh pr.sh >/dev/null) >/dev/null
to stderr
第二个命令仍然打印,因为继承的stderr
仍将发送到控制台。但是第一个没有打印任何内容,因为“2>&1”将内部的stderr
重定向到外部的stdout
,这将/dev/null
虽然我从未使用过这种结构,但可以想象,在(在脚本中,很可能)您希望运行程序的情况下,它可能会很有用,您可以将其
stdout
发送到一个文件,但将其stderr
转发给调用方,就好像它是“正常”输出一样,可能是因为该程序正在与其他一些程序一起运行,并且您希望第一个程序的“错误”输出与其他程序的“正常”输出是同一流的一部分。(可能这两个程序都是编译器,您希望捕获所有错误消息,但它们不同意将错误发送到哪个流。)默认情况下,您的终端会打印stdout和stderr。它们仍然是分开的溪流。