Zenity - выход из выхода CLI Handbrake

Моя цель - создать индикатор выполнения gtk с выходом HandBrakeCLI, используя zenity -progress. Я столкнулся с некоторыми корягами, и мне интересно, знает ли кто-нибудь о лучшем способе или может помочь мне с тем, что я сейчас делаю.

Нормальный выход:

HandBrakeCLI -i infile -o outfile --preset=iPad

Отображает

Кодирование: задание 1 из 1, 11.97% (72.81 fps, avg 86.78 fps, ETA 00h00m43s)

HandBrake подключается к командам tr и cut, поэтому у меня есть только те проценты, которые ожидают zenity.

HandBrakeCLI -i infile -o outfile --preset=iPad 2>&1 | tr -s '\r' '\n' | cut -b 24-28

Результаты в ожидании:

1.05 
1.06 
1.10 
1.10

Но выход сильно задерживается, а иногда даже не отображается. Если я использую только мое выражение tr, я получаю вывод выше на каждой строке, но это весь вывод, включая "Encoding: task......".

Это, как команда cut, не может идти в ногу с std из Handbrake. Я прочитал об использовании именованных каналов, создал один и направленный вывод HandBrake в канал, а затем в другом терминале попробовал команду tr и cut через канал, и это привело к той же задержке.

Использование подстроки awk print также приводит к той же задержке.

Я не могу понять. Я за индикатором zenity -progress, потому что мое задание HandBrake называется заданием MythTV, и мне бы хотелось, чтобы индикатор выполнения отображался, поэтому я знаю, когда и когда выполняется кодировка.

Ответ 1

Вы можете использовать найденные решения здесь, в stackexchange.

Например:

Программа stdbuf, которая является частью GNU coreutils.

stdbuf -i0 -o0 -e0 command

Другим примером является expect команда unbuffer, например

unbuffer long_running_command | print_progress

unbuffer подключается к long_running_command через псевдотерминал (pty), что заставляет систему рассматривать его как интерактивный процесс, поэтому не использует буферизацию 4-kiB в конвейере, которая является вероятной причиной задержки.

Для более длинных конвейеров вам может понадобиться отключить каждую команду (кроме последней), например

unbuffer x | unbuffer -p y | z

Ответ 2

Используя UNBUFFER, предложенный erik для использования с вашим первым сообщением, следующая команда выполняет трюк:

( HandBrakeCLI -i infile -o outfile --preset=iPad | 
        unbuffer -p grep -i "encoding: task " | 
        unbuffer -p cut -c24-25 ) | 
        zenity --progress --auto-close