将输出重定向到对话框仪表后获取 stderr

将输出重定向到对话框仪表后获取 stderr

我正在使用 python 文件来抓取链接,但是要做到这一点需要一些时间,它会打印33,66并且100通常会使用以下命令将链接打印到 stderrsys.write.stderr(var)

现在,我想运行这个命令python file.py | dialog --gauge "Doing stuffs" 10 35 0

并希望通过管道传输 stdout(33, 66, 100 用于更新百分比)来测量并将 sterr 获取到变量。

{ 
    python3 file.py 2>&3 | dialog --gauge "Doing stuffs" 10 35 0; 
} 3>&1

此命令正确运行对话框,然后打印 stderr,但我无法获取其输出,除非它在子 shell 中运行。但这样做会使对话框消失。

答案1

对您来说最简单的方法是将标准错误存储到文件中,然后在脚本完成后将该文件的内容分配给变量。

python file.py 2> ErrorFile | dialog --gauge "Doing stuffs" 10 35 0
MY_STDERR=$(<ErrorFile)

如果您不想使用中间文件,这里有另一种方法(取自这个答案,您还可以在其中查看说明):

{ MY_STDERR="$( { python file.py | dialog --gauge "Doing stuffs" 10 35 0; } 2>&1 1>&3 3>&- )"; } 3>&1;

答案2

让我们使用这个函数定义,它将百分比写入标准输出以及评论标准错误,作为您的程序的替代品python

thing() { for f in {10..100..10}; do sleep 0.5; echo "$f"; echo "Got $f" >&2; done; }

您可以捕获标准错误thing仍呈现仪表时的输出:

{ info=$( ( thing 2>&4 | dialog --gauge 'Gauge' 10 40 0 >&3 ) 4>&1 ) ; } 3>&1
printf "GOT> %s\n" "$info"

在这里我们thing捕获标准错误FD 4,并将输出从dialog --gauge临时发送到FD 3。分配变量$infoFD 4我们重定向FD 3回到标准输出。如果您不需要最终的重新分配,您可以通过删除外部花括号和重定向来简化表达式,使仪表显示保持打开状态标准错误

info=$( ( thing 2>&4 | dialog --gauge 'Gauge' 10 40 0 >&2 ) 4>&1 )
printf "GOT> %s\n" "$info"

答案3

另一种选择是这样的:

x=$( { dostuff | 
       dialog --gauge "Doing stuffs" 10 35 0 >/dev/tty 2>/dev/null; } 2>&1 )

这里,

  • (进度条)的标准输出dialog被直接重定向到终端,绕过其他任何内容
  • 的 stderrdialog被发送到/dev/null,因此我们不会从那里捕获任何垃圾
  • 的标准输出像往常一样通过管道python进入,并且dialog
  • 的 stderrpython被重定向(组外)到命令替换提供的“stdout”,并由 shell 捕获

当然,重定向意味着/dev/tty即使整个输出被重定向到其他地方,也会打印进度条。这可能是也可能不是您想要的(但是输出的终端控制代码的混乱dialog也可能不是除终端之外的任何地方都非常有用的东西)。

这也将隐藏 中的任何错误dialog,但整个分配的退出状态是管道中最后一个命令的退出状态,因此您可以检查它。或者用于set -o pipefail查看管道中的任一命令是否失败。

使用如下脚本进行测试dostuff

#!/bin/bash
for x in 0 1 2 3 4 5; do
    echo $((x * 20));
    sleep .5;
done
echo "this is the result" >&2

相关内容