【问题标题】:In bash, how to capture some output in variable, letting rest got to standard output在 bash 中,如何在变量中捕获一些输出,让休息到达标准输出
【发布时间】:2021-02-08 07:45:30
【问题描述】:

我知道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

【问题讨论】:

  • 每个文件描述符在执行程序时仅指向一个位置,即使该位置是执行奇特逻辑的单独程序的标准输入(例如读取第一行然后将其余部分转发到某处否则)。
  • 使用额外的 fd:sub.sh: echo hello; echo nasty >&3, main.sh: exec 3>&1; var=$(./sub.sh)

标签: bash output-redirect


【解决方案1】:

这可以通过引入一个 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 的内容进入到标准输出。

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    相关资源
    最近更新 更多