如何实时 grep 包含进度条的输出?

cal*_*doa 6 grep stdout progress-information

我正在使用一个工具(openocd)打印大量垃圾,然后一个基本进度条缓慢打印简单的点,然后再次打印一些垃圾。

我想过滤此输出,以便grep仅显示带有进度条的行,并且是实时的(即输出的每个点openocd立即打印在终端中):

openocd <args> |& grep '^\.'
Run Code Online (Sandbox Code Playgroud)

问题是grep(最多)是行缓冲的,因此进度条在完成之前不会显示。

我该如何处理grep,或者是否有任何标准替代方案可以实现此目的?如果有一种通过openocd配置的方法,这将很有用,尽管我更喜欢更通用的解决方案。

Cen*_*ane 6

这是一种黑客/不寻常的答案,事实是这很可能以一种不太干净的方式实现。


grep本身似乎只在遇到换行符时打印输出,您的进度栏在更新时可能不会引入换行符,因此您的问题。

strace是一个用于查看命令正在调用的系统调用的工具,这包括向内存/存储读取和写入内容,以及打开/关闭文件描述符等内容。


strace在管道被传递到 的情况下,您可以查看进程正在访问stout的内容grep,因此strace您可以查看正在馈送到 的文本grepstrace将定期发送来自管道命令的输出,您可以嗅探该输出并显示它。我正在测试rsync --progress,这似乎遇到了类似的情况。我使用了grep因为##%那是rsync用来显示进度的。

rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%"
Run Code Online (Sandbox Code Playgroud)

如果你运行这个命令,你会发现它strace没有很好的输出,但是当我使用它时,它strace捕获了一些通常不会read出现的 s ,显示s 为 0%、21%、45%、68%, 91% 和 100%,似乎每秒更新一次(可能基于更新进度的频率)。rsyncgrepwritereadrsync

因此,您可以通过再次调用相同的输出来获得不太好的grep输出。stracegrep

rsync --progress file1 file2 | strace -e trace=read grep "[0-9]*%" 2>&1 > /dev/null | grep -o "[0-9]*%"
Run Code Online (Sandbox Code Playgroud)

2>&1重要,因为strace打印在stderr. 重定向> /dev/nullstdout以防止报告/dev/null第一个的输出。grep最终结果是以下输出:

0%
21%
45%
68%
91%
100%
Run Code Online (Sandbox Code Playgroud)

你必须换掉grep,但看起来它可以解决问题。它并不漂亮,但它可以工作,并且可以绕过grep. 看起来像grep -f这样的工作tail -f会很方便(我知道grep -f已经在使用了)。

第一个主要是过滤掉将要执行的grep文本,因为只有匹配的行才会在调用中列出,但您还需要一些东西来让文本移动,以便可以观看它。stracereadstracereadstrace