理解大括号对重定向的影响 ("> file1 >& file2" vs. "{ > file1; } >& file2")

Bin*_*rus 3 bash io-redirection

请考虑以下 bash 脚本:

#!/bin/bash

touch ./temp

set -C

>./temp &>/dev/null      # Visible error message output ("./test7: line 7: ./temp: cannot overwrite existing file")

{ >./temp; } &>/dev/null # No error message
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么由倒数第二行中的重定向导致的错误消息没有被尾随抑制&>/dev/null,而它在最后一行中按预期工作?

我研究了 bash 手册中有关重定向和复合命令的段落(特别是有关组命令的部分),但无法从中做出解释。毕竟,由于花括号中只有一个命令,离开花括号应该不会改变任何东西,不是吗?差异是否与 bash 解析行的顺序有关?

pyn*_*exj 5

根据bash手册(man bash):

重定向按照它们出现的顺序进行处理,从左到右。[...] 请注意,重定向的顺序很重要。

对于> temp >& /dev/null,当 bash 处理> temp部件时,stderr 仍然指向 tty,因此您可以看到错误。您可以这样验证:

[STEP 101] $ set -C
[STEP 102] $ date >> temp
[STEP 103] $
[STEP 104] $ > temp
bash: temp: cannot overwrite existing file
[STEP 105] $ > temp >& /dev/null
bash: temp: cannot overwrite existing file
[STEP 106] $
[STEP 107] $ >& /dev/null > temp
[STEP 108] $ 2> /dev/null > temp
[STEP 109] $
Run Code Online (Sandbox Code Playgroud)

对于{ > temp; } &> /dev/null{ > temp; }被作为复合命令处理,其输出作为一个整体由 重定向&> /dev/null