我正在使用 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。分配变量$info
后FD 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
被直接重定向到终端,绕过其他任何内容 - 的 stderr
dialog
被发送到/dev/null
,因此我们不会从那里捕获任何垃圾 - 的标准输出像往常一样通过管道
python
进入,并且dialog
- 的 stderr
python
被重定向(组外)到命令替换提供的“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