为了账号安全,请及时绑定邮箱和手机立即绑定

将stdout捕获到变量,但仍将其显示在控制台中

/ 猿问

将stdout捕获到变量,但仍将其显示在控制台中

qq_笑_17 2019-12-27 10:44:03

我有一个bash脚本,它调用了几个长时间运行的进程。由于处理原因,我想将这些调用的输出捕获到变量中。但是,由于这些进程是长期运行的进程,因此我希望rsync调用的输出实时显示在控制台中,而不是事后显示。


为此,我找到了一种方法,但是它依赖于将文本输出到/ dev / stderr。我觉得输出到/ dev / stderr并不是一个好方法。


VAR1=$(for i in {1..5}; do sleep 1; echo $i; done | tee /dev/stderr)


VAR2=$(rsync -r -t --out-format='%n%L' --delete -s /path/source1/ /path/target1 | tee /dev/stderr)


VAR3=$(rsync -r -t --out-format='%n%L' --delete -s /path/source2/ /path/target2 | tee /dev/stderr)

在上面的示例中,我多次调用rsync,并且希望在处理文件时看到它们的名称,但是最后我仍然希望将输出结果包含在变量中,因为稍后将对其进行解析。


有没有一种“更清洁”的方式来实现这一目标?


如果有所作为,我正在使用Ubuntu 12.04,bash 4.2.24。



查看完整描述

3 回答

?
饮歌长啸

在您的shell中复制&1(在我的示例中为5),在子shell中使用&5(这样您将写入父shell的stdout(&1)):


exec 5>&1

FF=$(echo aaa|tee >(cat - >&5))

echo $FF

将打印aaa两次,一次是由于子外壳中的回显,而第二次将打印变量的值。


在您的代码中:


exec 5>&1

VAR1=$(for i in {1..5}; do sleep 1; echo $i; done | tee >(cat - >&5))

# use the value of VAR1


查看完整回答
反对 回复 2019-12-27
?
呼唤远方

Op De Cirkel的答案具有正确的想法。可以进一步简化(避免使用cat):


exec 5>&1

FF=$(echo aaa|tee /dev/fd/5)

echo $FF


查看完整回答
反对 回复 2019-12-27
?
HUWWW

这是捕获stderr命令和出口代码的示例。这是基于罗素·戴维斯(Russell Davis)的答案。


exec 5>&1

FF=$(ls /taco/ 2>&1 |tee /dev/fd/5; exit ${PIPESTATUS[0]})

exit_code=$?

echo "$FF"

echo "Exit Code: $exit_code"

如果该文件夹/taco/存在,它将捕获其内容。如果该文件夹不存在,它将捕获一条错误消息,并且退出代码为2。


如果省略,2>&1则只会stdout被捕获。


查看完整回答
反对 回复 2019-12-27

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信