You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

额外的()或{}如何改变Bash中重定向到/dev/null的内容?

Bash文件描述符重定向:嵌套括号为何改变输出?

我在测试Bash文件描述符重定向时发现两个命令输出结果截然不同:

命令1:

((echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&-)  2> /dev/null

命令2:

(echo STDOUT; echo STDERR >&2;) 3>&1 1>&2 2>&3 3>&-   2> /dev/null

我原本预期前者因stdout和stderr交换输出STDERR,后者输出STDOUT,但实际结果相反。额外的一层括号为何会改变输出?


编辑补充:文件描述符流向逻辑梳理

经解释后,两种场景的文件描述符指向逻辑如下:

场景1:双层括号((...))

  1. 初始状态:1指向终端标准输出,2指向终端标准错误
  2. 先处理内层子shell的交换重定向3>&1 1>&2 2>&3 3>&-,完成1和2的指向互换:此时1指向原标准错误,2指向原标准输出
  3. 再处理外层的2> /dev/null,将当前的2(原标准输出)重定向到/dev/null
  4. 执行命令:
    • echo STDOUT:写入当前1(原标准错误),最终输出到终端
    • echo STDERR >&2:写入当前2(/dev/null),被丢弃
      → 最终输出STDOUT

场景2:单层括号(...)

  1. 初始状态:1指向终端标准输出,2指向终端标准错误
  2. 先处理命令最后的2> /dev/null,将当前2重定向到/dev/null
  3. 再处理子shell的交换重定向3>&1 1>&2 2>&3 3>&-,完成1和2的指向互换:此时1指向/dev/null,2指向原标准输出
  4. 执行命令:
    • echo STDOUT:写入当前1(/dev/null),被丢弃
    • echo STDERR >&2:写入当前2(原标准输出),最终输出到终端
      → 最终输出STDERR

核心差异在于重定向的执行顺序:双层括号时,交换重定向先于2> /dev/null执行;单层括号时,2> /dev/null先于交换重定向执行,导致交换的是已经被重定向的描述符。


内容的提问来源于Stack Exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:05:19