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



我知道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的标准输出。

为了实现这种行为,上面需要用什么来替换魔术命令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

这可以通过引入额外的文件描述符来实现,如下所示。首先是用于测试的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的内容将成为标准输出。

最新更新