
[英]“$env” >| /dev/null , what is the redirection sign and the pipeline doing here?
[英]What is the extra set of () or {} doing to change what gets redirected to /dev/null?
我在 bash 上根据我对文件描述符重定向的理解做了一些测试,发现:
((echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&-) 2> /dev/null
和
(echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&- 2> /dev/null
给出了不同的结果。 第一个给出预期的STDERR
output,因为stdout
和stderr
fds 被交换,但第二个给出一个意想不到的STDOUT
output,就好像 fds 从来没有交换过一样。
这对我来说是令人惊讶的。 在这种情况下,我看不到额外的 par.netical 会做什么来更改 output。使用大括号具有相同的效果。
所以我认为的“预期”结果实际上是错误的,因为我错误地想象了正在发生的事情。 实际发生的是(-> 的左侧是文件描述符(或者在最后一列的情况下是命令),右侧是底层文件句柄 output 到的内容):
1 -> stdout 1 -. ,-> stdout 1 -. ,-> /dev/null echo STDOUT -> stderr
X X
2 -> stderr 2 -' '-> stderr 2 -' '-> stderr echo STDERR >&2 -> /dev/null
有了@JohnKugelman 的解释,现在这就说得通了。
1 -> stdout 1 -> stdout 1 -. ,-> stdout echo STDOUT -> /dev/null
X
2 -> stderr 2 -> /dev/null 2 -' '-> /dev/null echo STDERR >&2 -> stdout
重定向将首先处理,即使它们是在命令之后编写的。 这个事实很关键。 这意味着2> /dev/null
不是最后执行的。
尽管2> /dev/null
位于该行的末尾,但它实际上是在子 shell 启动之前执行的。 (subshell) 2>/dev/null
实际上是2>/dev/null (subshell)
。 这意味着它在第一个示例中交换描述符之前执行,但在第二个示例中执行。
让我们深入探讨一下。
((echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&-) 2> /dev/null
这相当于:
2>/dev/null (3>&1 1>&2 2>&3 3>&- (echo STDOUT; >&2 echo STDERR))
步骤是:
2> /dev/null
: fd 2 被重定向到/dev/null
。3>&1 1>&2 2>&3 3>&-
:交换 fds 1 和 2。echo STDOUT
:写入 fd 1,即/dev/null
。>&2
:fd 1被重定向到fd 2,也就是原来的shell的stdout。echo STDERR
:写入 fd 1,即标准输出。(echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&- 2> /dev/null
这相当于:
3>&1 1>&2 2>&3 3>&- 2>/dev/null (echo STDOUT; >&2 echo STDERR))
步骤是:
3>&1 1>&2 2>&3 3>&-
:交换 fds 1 和 2。2>/dev/null
:fd 2 被重定向到/dev/null
。echo STDOUT
:写入 fd 1,这是原始 shell 的 stderr。>&2
:fd 1 被重定向到 fd 2,即/dev/null
。echo STDERR
:写入 fd 1,即/dev/null
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.