在bash中,如何捕获变量中的一些输出,让其余的输出到标准输出

In bash, how to capture some output in variable, letting rest got to standard output

我知道 bash“捕获输出”功能,按照(两个单独的文件):

sub.sh:     echo hello
main.sh:    greeting="$(./sub.sh)"

这会将 greeting 变量设置为 hello

但是,我需要编写一个脚本,我只想捕获一些一些信息,让其余的达到“正常”标准输出:

sub.sh:     xyzzy hello ; plugh goodbye
main.sh:    greeting="$(./sub.sh)"

我想要的是 hello 被放置在 greeting 变量中,但是 goodbye 被发送到 main.sh.[=29 的标准输出=]

魔术命令 xyzzyplugh 需要用上面的内容替换什么(或者我可以在 main.sh 中做什么),以实现此行为?我 怀疑 它可以通过一些基于句柄的重定向的偷偷摸摸的摆弄来完成,但我不确定。如果不可能,我将不得不恢复将其中一项写入临时文件以供稍后使用,但我不想这样做。


为了让事情更清楚,这是我正在使用的测试用例(当前使用非工作文件句柄 3 方法)。首先 sub.sh:

echo xx_greeting >&3 # This should be captured to variable.
echo xx_stdout       # This should show up on stdout.
echo xx_stderr >&2   # This should show up on stderr.

然后main.sh:

greeting="$(./sub.sh)" 3>&1
echo "Greeting was ${greeting}"

而我运行因此:

./main.sh >/tmp/out 2>/tmp.err

希望看到以下文件:

/tmp/out:
    xx_stdout
    Greeting was xx_greeting 
/tmp/err:
    xx_stderr

这可以通过引入一个 extra 文件描述符来完成,如下所示。首先是用于测试的 sub.sh 脚本,它只是将不同的东西写入三个不同的描述符(第一个是隐式的 >&1):

echo for-var
echo for-out >&3
echo for-err >&2

二、main.sh里面调用的:

exec 3>&1
greeting="$(./sub.sh)"
echo "Variable is ${greeting}"

然后您只需 运行 它确保您知道什么输出将到达不同的位置:

pax> ./main.sh > xxout 2> xxerr

pax> cat xxout
for-out
Variable is for-var

pax> cat xxerr
for-err

因此你可以看到,当从 main.sh 调用 sub.sh 时,写入文件句柄 1 的内容进入捕获变量,写入文件句柄 2 的内容进入标准错误,等等写入文件句柄 3 到标准输出。