Подтвердить что ты не робот

Результат выполнения на месте в терминале или консоли

При запуске git clone он обновляет ход выполнения. Например, процент полученных объектов изменяется на месте.

[email protected]:~/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 или что-то еще более простое, например, какую-то комбинацию символов backspace и обычного символьного вывода?

Меня особенно интересует, как этот консольный вывод может быть выполнен с Ruby.

ИЗМЕНИТЬ

Отвечает мой первоначальный вопрос. Но здесь добавление. Например, когда вы используете MPlayer, он не только обновляет строку, чтобы показывать текущий прогресс, но также и предыдущую строку (например, когда вы нажимаете паузу).

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

Как бы вы обновили две строки вывода на месте?

4b9b3361

Ответ 1

Использовать возврат каретки. '\ r' обычно должен работать.

Ответ 2

git/progress.c

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

Git просто испускает возврат каретки и нет строки, которую терминал интерпретирует как "перемещение в первый столбец".

Ответ 4

Я написал небольшой класс для многострочного обновления:

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 [email protected]_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

Для Ruby существует ряд проклятий librbaries. Я считаю, что rbbcurse наиболее поддерживается.