bash文件描述符重定向
bash文件描述符重定向
我有以下两个bash脚本:
one.bash:
#!/bin/bash echo "我不能控制这行输出到stdout" echo "我不能控制这行输出到stderr" >&2 echo "我可以控制这行输出到fd 5" >&5
callone.bash:
#!/bin/bash # 在这里我尝试将stdout和stderr合并到stderr中。 # 然后将fd5定向到stdout。 bash ./one.bash 1>&2 5>&1
当我像这样运行它:
bash callone.bash 2>stderr.txt >stdout.txt
stderr.txt文件的内容如下:
我不能控制这行输出到stdout 我不能控制这行输出到stderr 我可以控制这行输出到fd 5
而stdout是空的。
我希望"我可以控制"这行只输出到stdout.txt。
对于更改的限制如下:
- 我可以更改callone.bash中的任何内容。
- 我可以更改我控制的one.bash中的那行。
- 我可以添加与文件描述符5相关的exec。
- 我必须按照指示运行脚本。
[编辑] 这种用法是:我有一个脚本,它可以运行其他脚本并输出到stderr和stdout。但是我需要确保用户只看到被控制的消息。所以我将被控制的消息发送到fd5,其他所有内容(stdout和stderr)都发送到日志文件。
在bash脚本中,文件描述符重定向是按顺序进行的。当你运行1>&2
时,你用文件描述符2替换了文件描述符1。所以当你运行5>&1
时,你将文件描述符5重定向到现在文件描述符1指向的位置(而不是它启动时的位置)。你需要交换这两个重定向的顺序:bash ./one.bash 5>&1 1>&2
。
有趣的是,当涉及到管道时,情况就不一样了。管道先设置,然后才是重定向。可以参考stackoverflow.com/a/12027221/1524545。
那么,什么不一样呢?管道在右边,但是先执行。噢,我明白了。虽然顺序不同,但它们还是按顺序执行的,只是你可能会有些错误的直觉。当你理解这些组件如何共同工作时,这种顺序才是有意义的。否则,很难正确使用(无法正确地使用管道进行重定向)。
所以,文件描述符重定向的问题出现的原因是顺序问题,而解决方法是调整重定向的顺序。