【问题标题】:Progress bar in a linux terminallinux终端中的进度条
【发布时间】:2012-10-25 13:50:15
【问题描述】:

我最近用 C++ 实现了一个进度条类。我写了类似的东西

cout << "\r" << percentage_done << "%" << flush;

现在我正在运行一些程序,将输出输出到 less。 问题是 less 向我展示了很多类型的行

^M1%^M2%...

所以“\r”没有被正确解释。是否有可能以这种方式进行管道传输 less 只会显示最后的 100% 行,还是我必须在我的程序中添加一个开关 完全禁用进度条?

当我将输出直接传输到文件时,我遇到了同样的问题,所以输出文件 不必要地占用大量磁盘空间。

【问题讨论】:

  • 可以选择关闭花哨的基于文本的 GUI 是惯用的。另外,最好使用 libncurses 进行统一终端访问。
  • 一切都按设计进行。如果终端连接到标准输出,您应该只显示进度条。
  • "\r" 在大多数系统上映射到 ^M - 回车,或返回行首而不前进到下一行(不同于 "\n",换行,这意味着要么移动到开头下一行或向下移动一行而不更改列);所以你得到了你想要的。正如其他人所提到的,如果cout 不是终端,您可能需要使用不同的格式。

标签: c++ shell pipe


【解决方案1】:

This approach 在没有额外选项的情况下使用更少的管道运行正常。它通常适用于任何类型的输出重定向。

而且您不必按照其他方法的建议检查 is_terminal:

#include <boost/progress.hpp>
#include <boost/timer.hpp>
#include <vector>

int main(int argc,char *argv[])
{
    const unsigned long expected_count=20;
    boost::progress_display show_progress( expected_count );
    for(int i=0;i!=expected_count;++i)
    {
        volatile std::vector<int> v(1024*1024*128);
        ++show_progress;
    }
    return 0;
}

输出是:

0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************

在progress_display 构造函数期间打印标尺。

然后进度条在++show_progress上逐渐被*填满;

【讨论】:

    【解决方案2】:

    less 使用-r 选项,让它解释控制序列。比较:

    echo -e '1\r2\r3\r4\r100' | less
    echo -e '1\r2\r3\r4\r100' | less -r
    

    【讨论】:

      【解决方案3】:

      嗯,我认为 Jan Hudec 说的非常正确。我给自己写了一个小函数

      #include <unistd.h>
      
      bool stdout_has_terminal()
      {
        return NULL != ttyname(STDOUT_FILENO);
      }
      

      根据返回值,我要么打印进度条,要么不打印。现在一切都很好:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-03
        • 1970-01-01
        • 2012-11-21
        • 2011-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多