При выполнении сценариев в bash или любой другой оболочке в * NIX при выполнении команды, которая займет более нескольких секунд, требуется индикатор выполнения.
Например, копирование большого файла, открытие большого файла tar.
Какими способами вы рекомендуете добавлять индикаторы выполнения в сценарии оболочки?
Ответы:
Вы можете реализовать это, переписав строку. Используйте
\r
для возврата к началу строки без записи\n
в терминал.Напишите,
\n
когда вы закончите продвигать линию.Использовать
echo -ne
для:\n
и\r
.Вот демо:
В комментарии ниже, puk упоминает, что это «не получается», если вы начинаете с длинной строки, а затем хотите написать короткую строку: в этом случае вам нужно будет перезаписать длину длинной строки (например, пробелами).
источник
printf
вместоecho
.printf "#### (50%%)\r"
он не будет работать с одинарными кавычками, а знак процента необходимо экранировать.Вы также можете быть заинтересованы в том, как сделать счетчик :
Могу ли я сделать спиннер в Bash?
источник
while :;do for s in / - \\ \|; do printf "\r$s";sleep .1;done;done
(*:sleep
может потребоваться целые числа, а не десятичные дроби)some_work ...
строке выше; более подробное обсуждение, основанное на этом полезном ответе и полезном комментарии Адама Каца - с акцентом на соответствие POSIX - можно найти здесь .\b
а не\r
, поскольку в противном случае он будет работать только в самом начале строки:while :; do for c in / - \\ \|; do printf '%s\b' "$c"; sleep 1; done; done
- или, если отображать курсор за спиннером нежелательно:printf ' ' && while :; do for c in / - \\ \|; do printf '\b%s' "$c"; sleep 1; done; done
job=$!
) и затем запуститьwhile kill -0 $job 2>/dev/null;do …
, например:sleep 15 & job=$!; while kill -0 $job 2>/dev/null; do for s in / - \\ \|; do printf "\r$s"; sleep .1; done; done
Некоторые сообщения показали, как отображать прогресс команды. Чтобы рассчитать это, вам нужно увидеть, насколько вы продвинулись. В системах BSD некоторые команды, такие как dd (1), принимают
SIGINFO
сигнал и сообщают о своем прогрессе. В системах Linux некоторые команды будут реагировать аналогичноSIGUSR1
. Если эта возможность доступна, вы можете направить свой вводdd
для контроля количества обработанных байтов.Кроме того, вы можете использовать,
lsof
чтобы получить смещение указателя чтения файла и, таким образом, рассчитать прогресс. Я написал команду с именем pmonitor , которая отображает ход обработки указанного процесса или файла. С его помощью вы можете делать такие вещи, как следующее.В моем блоге появилась более ранняя версия сценариев оболочки Linux и FreeBSD .
источник
awk
игры!Получил простую функцию индикатора выполнения, которую я написал на днях:
Или поймать его,
https://github.com/fearside/ProgressBar/
источник
printf "\rProgress : [${_fill// /▇}${_empty// / }] ${_progress}%%"
используйте команду linux pv:
http://linux.die.net/man/1/pv
он не знает размер, если он находится в середине потока, но он дает скорость и общее количество, и оттуда вы можете выяснить, сколько времени это займет, и получить обратную связь, чтобы вы знали, что он не завис.
источник
Я искал что-то более сексуальное, чем выбранный ответ, как и мой собственный сценарий.
предварительный просмотр
Источник
Я положил его на GitHub
progress-bar.sh
Применение
источник
progress-bar 100
GNU tar имеет полезную опцию, которая дает функциональность простого индикатора выполнения.
(...) Другое доступное действие контрольной точки - «точка» (или «.»). Он указывает tar печатать одну точку в стандартном потоке листинга, например:
Тот же эффект может быть получен путем:
источник
--checkpoint=.10
. Он также отлично работает при извлечении сtar -xz
.Более простой метод, который работает в моей системе с использованием утилиты pipeview (pv).
источник
Ничего подобного не видели, и все пользовательские функции здесь, кажется, фокусируются только на рендеринге, так что ... мое очень простое POSIX-совместимое решение ниже с пошаговыми пояснениями, потому что этот вопрос не тривиален.
TL; DR
Рендеринг индикатора выполнения очень прост. Оценка того, сколько из этого должно сделать, это другой вопрос. Вот как визуализировать (анимировать) индикатор выполнения - вы можете скопировать и вставить этот пример в файл и запустить его:
{1..20}
- значения от 1 до 20echo -n
- печатать без новой строки в концеecho -e
- интерпретировать специальные символы при печати"\r"
- возврат каретки, специальный символ для возврата в начало строкиВы можете заставить его воспроизводить любой контент с любой скоростью, поэтому этот метод очень универсален, например, часто используется для визуализации «взлома» в глупых фильмах, без шуток.
Полный ответ
Основная проблема заключается в том, как определить
$i
значение, т. Е. Сколько отображать индикатор выполнения. В приведенном выше примере я просто позволил увеличить его вfor
цикле, чтобы проиллюстрировать этот принцип, но реальное приложение будет использовать бесконечный цикл и вычислять$i
переменную на каждой итерации. Для осуществления указанного расчета необходимы следующие ингредиенты:В случае
cp
необходимости нужен размер исходного файла и размер целевого файла:stat
- проверить статистику файла-c
- вернуть отформатированное значение%s
- общий размерВ случае таких операций, как распаковка файла, вычисление исходного размера немного сложнее, но все же так же просто, как получить размер несжатого файла:
gzip -l
- показать информацию о zip-архивеtail -n1
- работа с 1 строкой снизуtr -s ' '
- перевести несколько пробелов в одно (сжать их)cut -d' ' -f3
- вырезать 3-ю колонку, разделенную пробеломВот суть проблемы, хотя. Это решение все менее и менее общее. Все расчеты фактического прогресса тесно связаны с доменом, который вы пытаетесь визуализировать, является ли это одной файловой операцией, таймером обратного отсчета, увеличением числа файлов в каталоге, операцией с несколькими файлами и т. Д., Поэтому не может быть повторно использован. Единственная повторно используемая часть - это рендеринг индикатора выполнения. Чтобы использовать его повторно, необходимо абстрагировать его и сохранить в файле (например
/usr/lib/progress_bar.sh
), а затем определить функции, которые рассчитывают входные значения, специфичные для вашего домена. Вот как может выглядеть обобщенный код (я также сделал$BAR
динамику, потому что люди просили об этом, остальное должно быть уже ясно):printf
- встроенный модуль для печати материалов в заданном форматеprintf '%50s'
- ничего не печатать, добавить 50 пробеловtr ' ' '#'
- перевести все пробелы в хэшИ вот как вы бы это использовали:
Очевидно, что его можно обернуть в функцию, переписать для работы с потоковыми каналами, переписать на другой язык, какой бы ни был ваш яд.
источник
Я также хотел бы внести свой собственный индикатор прогресса
Достигает точности субсимволов, используя половину блоков Unicode
Код включен
источник
Индикатор выполнения в стиле APT (не нарушает нормальный вывод)
РЕДАКТИРОВАТЬ: Для получения обновленной версии проверьте мою страницу GitHub
Я не был удовлетворен ответами на этот вопрос. То, что я лично искал, было модным индикатором прогресса, как видит APT.
Я взглянул на исходный код C для APT и решил написать собственный эквивалент для bash.
Этот индикатор будет оставаться в нижней части терминала и не будет мешать выводу на терминал.
Обратите внимание, что в настоящее время панель имеет ширину 100 символов. Если вы хотите масштабировать его до размера терминала, это также довольно легко сделать (обновленная версия на моей странице github хорошо справляется с этим).
Я опубликую свой сценарий здесь. Пример использования:
Скрипт (я настоятельно рекомендую вместо этого версию на моем github):
источник
Это позволяет вам визуализировать, что команда все еще выполняется:
Это создаст бесконечный цикл while, который выполняется в фоновом режиме и отображает «.» каждую секунду. Это будет отображаться
.
в оболочке. Запуститеtar
команду или любую команду, которую вы хотите. Когда эта команда завершается исполняющие затем убить последнее задание работает в фоновом режиме - который является бесконечным во время цикла .источник
Вот как это может выглядеть
Загрузка файла
Ожидание завершения работы
Простая функция, которая реализует это
Вы можете просто скопировать и вставить его в свой скрипт. Больше ничего не требуется для работы.
Пример использования
Здесь мы загружаем файл и перерисовываем индикатор выполнения на каждой итерации. Неважно, какое задание фактически выполняется, пока мы можем получить 2 значения: максимальное значение и текущее значение.
В приведенном ниже примере максимальное значение равно,
file_size
а текущее значение предоставляется некоторой функцией и вызываетсяuploaded_bytes
.источник
Большинство команд Unix не даст вам прямой обратной связи, с которой вы можете сделать это. Некоторые выдадут вам вывод на stdout или stderr, который вы можете использовать.
Для чего-то вроде tar вы можете использовать ключ -v и направить вывод в программу, которая обновляет небольшую анимацию для каждой строки, которую она читает. Когда tar записывает список файлов, которые он распаковывает, программа может обновить анимацию. Чтобы выполнить процент выполнения, вам нужно знать количество файлов и считать строки.
Насколько я знаю, cp не дает такого рода вывода. Чтобы отслеживать прогресс cp, вам нужно будет отслеживать исходные и конечные файлы и следить за размером получателя. Вы можете написать небольшую программу на c, используя системный вызов stat (2), чтобы получить размер файла. Это будет считывать размер источника, а затем опрашивать файл назначения и обновлять панель% complete в зависимости от размера файла, записанного на сегодняшний день.
источник
Мое решение отображает процентную долю архива, который в данный момент распаковывается и записывается. Я использую это, когда записываю образы корневой файловой системы 2 ГБ. Вам действительно нужен индикатор прогресса для этих вещей. Что я делаю, это использую,
gzip --list
чтобы получить полный несжатый размер тарбола. Исходя из этого, я вычисляю фактор блокировки, необходимый для разделения файла на 100 частей. Наконец, я печатаю сообщение контрольной точки для каждого блока. Для файла объемом 2 ГБ это дает около 10 МБ блока. Если он слишком велик, вы можете разделить BLOCKING_FACTOR на 10 или 100, но тогда будет сложнее вывести симпатичный результат в процентах.Предполагая, что вы используете Bash, вы можете использовать следующую функцию оболочки
источник
Прежде всего, бар - это не единственный индикатор хода трубы. Другой (может быть, даже более известный) - pv (pipe viewer).
Во-вторых, bar и pv можно использовать, например, так:
или даже:
Один полезный трюк, если вы хотите использовать bar и pv в командах, которые работают с файлами, указанными в аргументах, таких как, например, copy file1 file2, - это использовать подстановку процесса :
Подстановка процессов - это волшебство bash, которое создает временные файлы fifo pipe / dev / fd / и подключает стандартный вывод из запущенного процесса (в круглых скобках) через этот канал, и копия видит его как обычный файл (за одним исключением, он может только читать его). вперед).
Обновить:
Сама команда bar также позволяет копировать. После бара человек:
Но процесс замены, по моему мнению, является более общим способом сделать это. Он использует саму программу cp.
источник
Я предпочитаю использовать диалог с параметром --gauge . Очень часто используется в установочных пакетах .deb и других элементах базовой конфигурации многих дистрибутивов. Таким образом, вам не нужно изобретать велосипед ... снова
Просто введите значение от 1 до 100 @stdin. Один простой и глупый пример:
У меня есть этот файл / bin / Wait (с chmod u + x perms) для приготовления пищи: P
Так что я могу поставить:
Wait "34 min" "warm up the oven"
или
Wait "dec 31" "happy new year"
источник
для меня самый простой в использовании и самый красивый вид пока это команда
pv
илиbar
какой-то парень уже написалнапример: необходимо сделать резервную копию всего диска с
dd
обычно вы используете
dd if="$input_drive_path" of="$output_file_path"
с этим
pv
вы можете сделать это так:dd if="$input_drive_path" | pv | dd of="$output_file_path"
и прогресс идет прямо к
STDOUT
этому:после того, как это сделано, сводится
источник
pv
илиbar
для визуализации хода выполнения различных процессов, например, таймера обратного отсчета, положения в текстовом файле, установки вашего приложения, настройки времени выполнения и т. Д.?Многие ответы описывают написание ваших собственных команд для распечатки
'\r' + $some_sort_of_progress_msg
. Иногда проблема заключается в том, что распечатка сотен этих обновлений в секунду замедляет процесс.Однако, если какой-либо из ваших процессов выдает результат (например
7z a -r newZipFile myFolder
, выводит каждое имя файла по мере его сжатия), тогда существует более простое, быстрое, безболезненное и настраиваемое решение.Установите модуль Python
tqdm
.Помощь:
tqdm -h
. Пример использования дополнительных параметров:В качестве бонуса вы также можете использовать,
tqdm
чтобы обернуть итерируемые в код Python.https://github.com/tqdm/tqdm/blob/master/README.rst#module
источник
tqdm
STDOUTwc -l
через трубу. Вы, вероятно, хотите избежать этого.tqdm
будет показывать прогресс вSTDERR
то время как по конвейеру своего вкладаSTDIN
вSTDOUT
. В этом случаеwc -l
должен получить тот же вход, как если быtqdm
он не был включен.Основываясь на работе Эдуарда Лопеса, я создал индикатор выполнения, который соответствует размеру экрана, каким бы он ни был. Проверьте это.
Он также размещен на Git Hub .
наслаждаться
источник
https://github.com/extensionsapp/progre.sh
Создайте 40-процентный прогресс:
progreSh 40
источник
Это применимо только с использованием gnome zenity. Zenity предоставляет отличный нативный интерфейс для скриптов bash: https://help.gnome.org/users/zenity/stable/
Пример с индикатора прогресса Zenity:
источник
Я использовал ответ из Создание строки повторяющихся символов в сценарии оболочки для повторения символов. У меня есть две относительно небольшие версии bash для сценариев, которые должны отображать индикатор выполнения (например, цикл, который проходит через много файлов, но не полезен для больших файлов tar или операций копирования). Более быстрый состоит из двух функций, одна из которых предназначена для подготовки строк для отображения панели:
и один для отображения индикатора выполнения:
Это может быть использовано как:
что означает подготовить строки для бара с 50 символами "#", и после этого:
отобразит количество символов «#», соответствующее соотношению 35/80:
Имейте в виду, что функция отображает строку в одной и той же строке снова и снова, пока вы (или какая-либо другая программа) не напечатаете новую строку. Если вы установите -1 в качестве первого параметра, строка будет стерта:
Более медленная версия все в одной функции:
и его можно использовать как (тот же пример, что и выше):
Если вам нужен прогрессбар на stderr, просто добавьте
>&2
в конце каждой команды printf.источник
Чтобы указать прогресс деятельности, попробуйте следующие команды:
ИЛИ
ИЛИ
ИЛИ
Внутри цикла while можно использовать флаги / переменные для проверки и отображения значения / степени прогресса.
источник
Используя предложения, перечисленные выше, я решил реализовать свой собственный индикатор выполнения.
источник
percent_none="$(( 100 - "$percent_done" ))"
наpercent_none="$(( 100 - $percent_done))"
Я сделал чистую версию оболочки для встроенной системы, используя преимущества:
Функция обработки сигналов в / usr / bin / dd SIGUSR1.
По сути, если вы отправите 'kill SIGUSR1 $ (pid_of_running_dd_process)', он выдаст сводную информацию о скорости передачи и количестве переданных.
создание фонового dd, регулярный запрос его обновлений и генерация тиков хеша, как это делали старые ftp-клиенты.
Использование / dev / stdout в качестве места назначения для не дружественных для stdout программ, таких как scp
Конечный результат позволяет вам выполнить любую операцию по передаче файла и получить обновление прогресса, которое выглядит как вывод старой хеш-функции с FTP, где вы просто получите хеш-метку для каждого X байтов.
Это вряд ли код качества производства, но вы поняли идею. Я думаю, что это мило.
Что бы это ни стоило, фактическое количество байтов может не отражаться правильно в количестве хэшей - у вас может быть один больше или меньше в зависимости от проблем округления. Не используйте это как часть тестового сценария, это просто конфетка. И да, я знаю, что это ужасно неэффективно - это сценарий оболочки, и я не извиняюсь за это.
Примеры с wget, scp и tftp приведены в конце. Он должен работать со всем, что имеет данные. Убедитесь, что вы используете / dev / stdout для программ, которые не подходят для stdout.
Примеры:
источник
pidof dd
этом страшно.$!
сdd
и ждать[[ -e /proc/${DD_PID} ]]
.Если вам нужно показать временную шкалу прогресса (заранее зная время показа), вы можете использовать Python следующим образом:
Затем, предполагая, что вы сохранили скрипт Python как
progressbar.py
, можно показать индикатор выполнения из вашего скрипта bash, выполнив следующую команду:Он будет отображать индикатор выполнения размером с
50
символы и «работает» в течение10
нескольких секунд.источник
Я основывался на ответе, представленном страхом
Это подключается к базе данных Oracle для получения информации о ходе восстановления RMAN.
источник
Можно создать функцию, которая рисует это в масштабе, скажем, 1-10 для количества баров:
источник
вывод:
примечание: если вместо 255 вы введете 1, вы будете контролировать стандарт на ... с 2 на стандарт на выходе (но вы должны изменить источник, чтобы установить "tot" в соответствии с прогнозируемым размером выходного файла)
источник