繁体   English   中英

额外的一组 () 或 {} 用来改变重定向到 /dev/null 的内容是什么?

[英]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,因为stdoutstderr 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))

步骤是:

  1. 2> /dev/null : fd 2 被重定向到/dev/null
  2. 外部子外壳启动。
  3. 3>&1 1>&2 2>&3 3>&- :交换 fds 1 和 2。
  4. 内部子外壳启动。
  5. echo STDOUT :写入 fd 1,即/dev/null
  6. >&2 :fd 1被重定向到fd 2,也就是原来的shell的stdout。
  7. 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))

步骤是:

  1. 3>&1 1>&2 2>&3 3>&- :交换 fds 1 和 2。
  2. 2>/dev/null :fd 2 被重定向到/dev/null
  3. 子外壳启动。
  4. echo STDOUT :写入 fd 1,这是原始 shell 的 stderr。
  5. >&2 :fd 1 被重定向到 fd 2,即/dev/null
  6. echo STDERR :写入 fd 1,即/dev/null

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM