在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 的标准输出=]
魔术命令 xyzzy
和 plugh
需要用上面的内容替换什么(或者我可以在 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 到标准输出。
我知道 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 的标准输出=]
魔术命令 xyzzy
和 plugh
需要用上面的内容替换什么(或者我可以在 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 到标准输出。