bash文件描述符重定向

21 浏览
0 Comments

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。

对于更改的限制如下:

  1. 我可以更改callone.bash中的任何内容。
  2. 我可以更改我控制的one.bash中的那行。
  3. 我可以添加与文件描述符5相关的exec。
  4. 我必须按照指示运行脚本。

[编辑] 这种用法是:我有一个脚本,它可以运行其他脚本并输出到stderr和stdout。但是我需要确保用户只看到被控制的消息。所以我将被控制的消息发送到fd5,其他所有内容(stdout和stderr)都发送到日志文件。

0
0 Comments

在bash脚本中,文件描述符重定向是按顺序进行的。当你运行1>&2时,你用文件描述符2替换了文件描述符1。所以当你运行5>&1时,你将文件描述符5重定向到现在文件描述符1指向的位置(而不是它启动时的位置)。你需要交换这两个重定向的顺序:bash ./one.bash 5>&1 1>&2

有趣的是,当涉及到管道时,情况就不一样了。管道先设置,然后才是重定向。可以参考stackoverflow.com/a/12027221/1524545

那么,什么不一样呢?管道在右边,但是先执行。噢,我明白了。虽然顺序不同,但它们还是按顺序执行的,只是你可能会有些错误的直觉。当你理解这些组件如何共同工作时,这种顺序才是有意义的。否则,很难正确使用(无法正确地使用管道进行重定向)。

所以,文件描述符重定向的问题出现的原因是顺序问题,而解决方法是调整重定向的顺序。

0