Какой бы ваш скрипт не был диалоговым, «само дерево жужжать не может», а в скрипте обычно жужжат утилиты, которые о диалоговых окнах представления не имеют. Так вот прикрутим контролируемый прогрессбар (--gauge
) из виджетов dialog
к всем известному wget
.
#!/bin/bash
FADDR="http://tolik-punkoff.com/static/test.mp3"
wget --progress=dot -O "./test.mp3" "$FADDR" 2>&1 |\
stdbuf -o0 awk '/[.] +[0-9][0-9]?[0-9]?%/ { print substr($0,63,3) }' | \
dialog --gauge "Download file from $FADDR" 10 100
1. Если просто запустить wget
без параметра --progress=dot
(параметр -O "./test.mp3"
здесь показывает путь и имя для сохраняемого файла, для теста оно у нас жестко задано), то wget
попытается нарисовать свой плохенький progressbar:
Использование параметра --progress=dot
приводит вывод на экран в такой вид:
Теперь у нас видны проценты, которые выводятся по штуке на строчку через определенный интервал времени по внутреннему алгоритму wget
.
2. wget
почему-то выводит сообщения о своей работе не на stdout
, а на stderr
. Аж морово поветрие какое-то, ибо и некоторые другие утилиты тоже выводят на stderr
. Оправданно на stderr
выводит сообщения только dialog
, тому ще он всю псевдографику выводит на stdout
. Отучаем wget
писать на stderr
вместо stdout
:
2>&1
2
— зарезервированный канал для stderr
1
— для stdout
. Тут мы просто перенаправляем один канал в другой.
3. Меняем буферизацию. На самом деле, буфер консоли (терминала) выводит на экран сообщение, если в буфере консоли накопилось 1024 байта. Или программа завершилась. Иначе нет. С помощью утилиты stdbuf
устанавливаем буфер stdout
(-o
) в ноль (-o0
), тем самым мы добиваемся, чтоб символы сразу поступали на вход awk
. stdbuf
в качестве второго параметра требует программу, которой она будет посылать измененный буфер. В данном случае awk
.
buffering in standard streams
man stdbuf на русском
За разъяснение спасибо другу из Телеграм.
4. Далее вывод wget
‘а передается awk
, которая хитрой регуляркой и оператором substr
вырезает из вывода все, кроме значений процентов.
5. dialog --gauge
может принимать из stdout
числа, и отображать их в виде progressbar’а