Bash脚本 - 将子脚本的标准错误输出重定向到父进程的标准输出

6

我相信我错过了一些简单的东西,但我正在使用一个执行脚本来调用几个实用程序脚本,并且我想通过一个管道处理所有实用程序的输出。我的问题是这些实用程序使用stderr来报告错误条件,但我不能在父脚本中捕获它们。

父脚本:

#!/bin/bash
child 2>&1 >/dev/null

子脚本

#!/bin/bash
echo "Print"
echo "Error" 1>&2

我期望的是,child(以及它的所有命令)的stderr被重定向到stdout(因此没有输出),但当我执行parent时,终端会回显Error("Print"被发送到/dev/null)。
2个回答

10
发生的事情是将stderr重定向到stdout的文件句柄(可能是/dev/stdout)。然后,将stdout重定向到/dev/null。但是,stderr仍然指向/dev/stdout。
为了忽略所有输出,请先将stdout重定向,然后将stderr重定向到stdout。
child >/dev/null 2>&1

或者,更简单的方法是由于您使用的是特定的bash,将标准输出和标准错误一起重定向:

child &>/dev/null

1
运算次序。谢谢,工作得很好,我感觉和我想的一样愚蠢。 - Sam
别自责,我花了很长时间才理解那个。 - glenn jackman

2
这不是对楼主问题的回答,但如果有其他人在苦苦思考如何将子进程的输出重定向到父进程的stdout,那么这里就是方法。
#!/bin/bash
child &>>/dev/stdout &

这个可以解决问题,即使在后台运行子任务也可以正常工作,如例所示。
感谢@glenn jackman,他是在全天搜寻解决方案时第一个提到在他的答案中使用/dev/stdout的人。

更新

经过进一步研究,这个答案特别有帮助,似乎有一种方法可以同时保留父进程的stderr
#!/bin/bash
child 1>&1 2>&2 &

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接