Как отобразить количество строк, выводимых командой, в реальном времени?

Как отобразить количество строк, выводимых командой, в реальном времени?

Я использую его svn exportкак часть скрипта упаковщика для своего приложения, и похоже, что эта команда, как и многие другие, не имеет никакого индикатора выполнения.

На данный момент у меня есть два варианта:

  • использовать его без опций и наблюдать, как он печатает тысячи строк
  • использую --quietи ничего не вижу, пока он не завершится.

Есть ли способ хотя бы показать количество строк, выводимых командой, в реальном времени? Например:

Exporting SVN directory ... 1234 files

И посмотрите на это число1234 приращение в реальном времени? Я могу представить передачу вывода команде, которая будет делать именно это, но какой?

решение1

yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

Или поместите заключенный в скобки раздел в скрипт оболочки. Обратите внимание, что это работает только в том случае, если ваша оболочка действительно поддерживает оператор преинкремента, например bash, ksh93 или zsh. В противном случае вам придется увеличить, $Iа затем вывести его (как в I=$((I+1));printf...). Кроме того, если printfне является встроенной функцией вашей оболочки (она является встроенной функцией текущего bash), вы можете использовать echo -neили print -nвместо этого для лучшей производительности. Вы просто хотите подавить новую строку и интерпретировать \r как экранирующий символ.

решение2

Это грубая идея, но вы можете использовать pvкоманду для подсчета количества строк по мере их прохождения и отображения результатов на экране. pvСреди множества переключателей есть -lпереключатель, который подсчитывает каждую строку по мере ее прохождения.

Пример

Здесь я использую цикл while для имитации некоторых файлов из вашего вывода SVN.

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

Он будет продолжать перезаписывать выходную строку следующим образом:

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]

решение3

Вы можете запустить свою команду в фоновом режиме как задание и перенаправить ее stdout (и stderr по желанию) в файл журнала: command > logfile &где &обозначает задание (если также stderr, то &>вместо >).

Затем вы можете использовать утилиту Wordcount для подсчета количества строк в вашем лог-файле с помощью wc -l.

Чтобы показать изменение состояния в одной динамически изменяющейся строке, можно использовать что-то вроде while true; do echo -en '\r'; wc -l logfile; sleep 1; done, но я не могу заставить bash нарисовать \rвозврат каретки, чтобы уничтожить содержимое предыдущей строки.

Посмотрите на этот вопрос, он почти дубликат:https://stackoverflow.com/questions/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash

Связанный контент