Создание индикатора выполнения с «диалогом» из вывода rsync

16

Я ищу способ отфильтровать / перенаправить вывод rsync таким образом, чтобы он мог быть передан в команду "dialog --gauge", чтобы я мог получить красивый индикатор выполнения во время синхронизации файлов. В настоящее время я только протестировал это непосредственно в приглашении, но я планирую сделать это в сценарии оболочки (bash).

Я просмотрел интернет и нашел кусочки, но мне все еще не хватает чего-то, чтобы это работало

(Отказ от ответственности: это может быть совершенно неправильный подход, и это чудовище перенаправления / обвязки)

Что я сейчас собрал:

rsync -avz --progress -e "ssh" user@server:/home/user/data/ /home/user/data | awk -f /home/user/rsync.awk | sed 's/\([0-9]*\).*/\1/' | dialog --title "My Gauge" --gauge "Hi, this is a gauge widget" 20 70

Сначала у меня есть команда rsync с параметром --progress. Вывод из rsync передается в awk и использует следующий фильтр awk:

{
   if (index($0, "to-check=") > 0)
   {
        split($0, pieces, "to-check=")
        split(pieces[2], term, ")");
        split(term[1], division, "/");
        print (1-(division[1]/division[2]))*100
}
#   else
#   {
#       print "#"$0;
#   }
   fflush();
}

Это отфильтровывает вывод rsync и предоставляет процент в следующем формате:

53.7037
55.5556
57.4074
59.2593
61.1111
62.963

Чтобы избавиться от десятичных чисел, я передаю вывод sed:

sed 's/\([0-9]*\).*/\1/'

Что дает следующий вывод:

64
66
68
70
72
74
75
77

Эти цифры вводятся в диалог, как это:

dialog --title "My Gauge" --gauge "Hi, this is a gauge widget" 20 70 

Насколько я знаю, "dialog --gauge" и т. Д. Должны принять это, но он просто показывает прогресс, равный 0%, пока не достигнет внезапно 100%

Может ли кто-нибудь указать мне правильное направление здесь? Я далеко от рабочего индикатора? Есть ли лучший способ добиться этого?

С Уважением,

Кристер

РЕДАКТИРОВАТЬ : После учета ответа @lynxlynxlynx ', правильная командная строка:

rsync -avz --progress -e "ssh" user@server:/home/user/data/ /home/user/data \ 
 | awk -f /home/user/rsync.awk \ 
 | sed --unbuffered 's/([0-9]*).*/\1/' \ 
 | dialog --title "My Gauge" --gauge "Hi, this is a gauge widget" 20 70
chr1573r
источник
1
Похоже, что-то (вероятно, awk) буферизует вывод до тех пор, пока программа перед тем, как он в конвейере не отправит EOF. Не знаю, как это проверить или решить, хотя ...
Шадур

Ответы:

12
for i in 10 20 30; do echo $i; sleep 1; done | dialog --title "My Gauge" --gauge "Hi, this is a gauge widget" 20 70

работает нормально, поэтому @Shadur прав и есть буферизация в игре.

Добавление sed стриппера в смесь показывает, что это виновник (показывает только 0 и 30):

for i in 10 20 30; do echo $i; sleep 1; done | sed 's/\([0-9]*\).*/\1/' | dialog --title "My Gauge" --gauge "Hi, this is a gauge widget" 20 70

Теперь, когда проблема известна, у вас есть несколько вариантов. Самым чистым было бы округлить / сократить процент awkс помощью математических или строковых манипуляций, но так как у вас есть GNUsed , просто добавьте -uили --unbufferedсделайте дело.

Однако для полноты картины простой тестовый пример awkтакже выполняет буферизацию:

for i in 10 20 30; do echo $i; sleep 1; done | awk '{print $0}' | sed -u 's/\([0-9]*\).*/\1/' | dialog --title "My Gauge" --gauge "Hi, this is a gauge widget" 20 70 

Но вы уже справились с этим fflush, поэтому я не ожидаю проблем.

lynxlynxlynx
источник
Вау..! Бесконечно благодарен! Добавление --unbuffered для sed - единственное, что нужно! Спасибо, что поделились своим временем и знаниями Shadur & lynxlynxlynx!
chr1573r
Для других людей, которым интересно, как выглядит последняя команда: rsync -avz --progress -e "ssh" user @ server: / home / user / data / / home / user / data | awk -f /home/user/rsync.awk | sed --unbuffered 's / ([0-9] *). * / \ 1 /' | dialog --title "My Gauge" --gauge "Привет, это виджет датчика" 20 70
chr1573r
Нет проблем, и добро пожаловать на сайт. :)
Шадур