shell里的|&用法

shell中默认的管道是将前边的命令执行的的标准输出结果传给管道后的命令,而标准错误输出是没有传递的,有些时候,我们想要对前边的命令的标准错误输出也做处理,这样的话就需要将stderr给重定向到stdout了。

不过在高版本的bash里和zsh里现在都支持了 |& 来将标准输出和错误输出一并交给后边的命令处理。举个例子:

$ cat test.sh 
#!/bin/bash
echo "stdout message"
echo "stderr message" 1>&2

我们模拟了2个输出,第一个是标准输出,第二个是错误输出。如果我们用普通的管道 | 来连接的话:

$ ./test.sh | grep stdout
stderr message
stdout message

我们本来只想要过滤包含”stdout”的内容,但错误输出的内容并不会经过管道处理,所以其内容还是完整的打印在了终端上。如果采用 |& 就会把两个输出内容一并交给管道来处理了:

$ ./test.sh |& grep stdout  
stdout message

我不确定bash是从哪个版本开始支持这个特性的,最早是csh/tcsh里有这个特性,被bash和zsh学过来了,ksh里|&是另外一种用法,表示的是协同处理。

如果你的shell不支持这个用法,还是老实的用重定向来解决吧:

$ ./test.sh 2>&1 | grep stdout
stdout message

上面的例子没有实际价值,可能有人说把 2>/dev/null 就可以了,实际应用中,可能是碰到某些命令的输出不确定我们想要的内容是在标准输出里还是在错误输出里,比如我们想看到scalac的选项里包含warn关键字的:

$ scalac -Y |& grep warn 
-Yinline-warnings                       Emit inlining warnings. (Normally surpressed due to high volume)
-Ywarn-adapted-args                     Warn if an argument list is modified to match the receiver.
-Ywarn-dead-code                        Warn when dead code is identified.
-Ywarn-inaccessible                     Warn about inaccessible types in method signatures.
-Ywarn-infer-any                        Warn when a type argument is inferred to be `Any`.
-Ywarn-nullary-override                 Warn when non-nullary `def f()' overrides nullary `def f'.
-Ywarn-nullary-unit                     Warn when nullary methods return Unit.
-Ywarn-numeric-widen                    Warn when numerics are widened.
-Ywarn-unused                           Warn when local and private vals, vars, defs, and types are are unused
-Ywarn-unused-import                    Warn when imports are unused
-Ywarn-value-discard                    Warn when non-Unit expression results are unused.

发表评论

电子邮件地址不会被公开。 必填项已用*标注