在 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:
添加前缀,因为它永远不会穿过管道。在第二个例子中确实如此。