代码之家  ›  专栏  ›  技术社区  ›  dan

终端或控制台中的就地进度输出

  •  32
  • dan  · 技术社区  · 16 年前

    当你奔跑 git clone ,它会及时更新进度。例如,对象在适当位置接收更改的百分比。

    user@athena:~/cloj/src$ git clone git://git.boinkor.net/slime.git
    Initialized empty Git repository in /home/user/cloj/src/slime/.git/
    remote: Counting objects: 15936, done.
    remote: Compressing objects: 100% (5500/5500), done.
    Receiving objects:  28% (4547/15936), 3.16 MiB | 165 KiB/s
    

    这是怎么形成的?它是否使用ncurses或更简单的东西,比如退格字符和正则字符输出的组合?

    我特别感兴趣的是如何通过ruby实现这种控制台输出。

    编辑

    我原来的问题得到了回答。但这里有个附录。例如,当您使用mplayer时,它不仅更新一行以显示当前进度,而且 以前的 行(例如,当您按暂停键时)。

     =====  PAUSE  =====
    A:  79.9 (01:19.9) of 4718.0 ( 1:18:38.0)  0.3% 
    

    如何更新两行输出?

    5 回复  |  直到 9 年前
        1
  •  38
  •   Aryabhatta    16 年前

    使用回车。\ R'通常会起作用。

        2
  •  7
  •   ephemient    16 年前

    git/progress.c

    ...
            eol = done ? done : "   \r";
    ...
                    fprintf(stderr, "...%s", ..., eol);
                    fflush(stderr);
    

    git只发出一个回车,没有换行,终端将其解释为“移动到第一列”。

        3
  •  4
  •   Ivan Black    9 年前
        4
  •  2
  •   Artem P    9 年前

    我为多行输出更新编写了一个小类:

    class ConsoleReset
      # Unix
      # Contains a string to clear the line in the shell
      CLR = "\e[0K"
      # ANSI escape sequence for hiding terminal cursor
      ESC_CURS_INVIS = "\e[?25l"
      # ANSI escape sequence for showing terminal cursor
      ESC_CURS_VIS   = "\e[?25h"
      # ANSI escape sequence for clearing line in terminal
      ESC_R_AND_CLR  = "\r#{CLR}"
      # ANSI escape sequence for going up a line in terminal
      ESC_UP_A_LINE = "\e[1A"
    
      def initialize
        @first_call = true
      end
    
      def reset_line(text = '')
        # Initialise ANSI escape string
        escape = ""
    
        # The number of lines the previous message spanned
        lines = text.strip.lines.count - 1
    
        # Clear and go up a line
        lines.times { escape += "#{ESC_R_AND_CLR}#{ESC_UP_A_LINE}" }
    
        # Clear the line that is to be printed on
        # escape += "#{ESC_R_AND_CLR}"
    
        # Console is clear, we can print!
        STDOUT.print escape if !@first_call
        @first_call = false
        print text
      end
    
      def hide_cursor
        STDOUT.print(ESC_CURS_INVIS)
      end
    
      def show_cursor
        STDOUT.print(ESC_CURS_VIS)
      end
    
      def test
        hide_cursor
    
        5.times do |i|
          line = ['===========================================']
          (1..10).each do |num|
            line << ["#{num}:\t#{rand_num}"]
          end
          line << ['===========================================']
          line = line.join("\n")
          reset_line(line)
          sleep 1
        end
    
        show_cursor
    
        puts ''
      end
    
      private
        def rand_num
          rand(10 ** rand(10))
        end
    end
    

    受到启发 prydonius/spinning_cursor . 见 test 方法,例如用法。

        5
  •  0
  •   Farrel    16 年前

    ruby有很多诅咒librbaries。我相信rbbcurse是维护最多的。

    推荐文章