理解管道中的|&

理解管道中的|&

在 bash 手册中https://www.gnu.org/software/bash/manual/html_node/Pipelines.html 它指出:

如果|&使用 ' ',command1则 的标准错误除了其标准输出之外,还会command2通过管道连接到 的标准输入;它是 的简写2>&1 |

我向社区提出的问题是,它的实际意义是什么。我做了一个测试来证明为什么我认为它没有任何作用。

在这里,我创建了一个有效的循环,然后在最后一行创建了一个错误:

items="frog cat"
for item in $items
do 
echo $item
done

for item i will make error this line

因此,手册暗示的是,除非我使用 |&,否则 stderr 将不会在 stdout 中输出,因为它会通过管道传输到下一个命令。所以我测试了一下:

## this shows a regular pipe without &.  As you can see stderr gets written anyway
$ ./testing.sh  | grep error
./testing.sh: line 7: syntax error near unexpected token `i'
./testing.sh: line 7: `for item i will make error this line'

## this shows a pipe with |& in it.  
$ ./testing.sh  |& grep error
./testing.sh: line 7: syntax error near unexpected token `i'
./testing.sh: line 7: `for item i will make error this line'

是的,无论如何,stderror 都会写入下一个管道命令,而无需&|.那么那还有什么意义呢|&

答案1

stderr 不是“无论如何都写入下一个管道命令”,它被写入默认情况下进入终端的 stderr 。

bash 参考手册说:

它是 的简写2>&1 |。将标准错误隐式重定向到标准输出是在 command1 指定的任何重定向之后执行的。

这意味着 stderr 在通过管道发送之前将被重定向到 stdout。

$ cat stderr.sh
#!/usr/bin/env bash


echo 'This is an error' >&2
echo 'This is not'

当我们运行它时,我们会在 stdout 和 stderr 上看到输出:

$ ./stderr.sh
This is an error # This is displayed on stderr
This is not # this is displayed on stdout

当我将 stdout 重定向到时,/dev/null我只看到 stderr:

$ ./stderr.sh >/dev/null
This is an error

同样,如果我将 stderr 重定向到/dev/null我只看到 stdout:

$ ./stderr.sh 2>/dev/null
This is not

这里我们可以使用这个 sed 命令来进一步说明是什么让它通过管道:

$ ./stderr.sh | sed 's/^/Via the pipe: /'
This is an error
Via the pipe: This is not

$ ./stderr.sh |& sed 's/^/Via the pipe: /'
Via the pipe: This is an error
Via the pipe: This is not

在第一个示例中,错误没有Via the pipe:添加前缀,因为它永远不会穿过管道。在第二个例子中确实如此。

相关内容