Кнопка отмены Zenity для индикатора выполнения параллельного выполнения GNU

Вы можете использоватьecho -e "\tblabla":

$ echo -e "\tblabla\n\t\tblibli\n\t\t\tbloblo\n"
    blabla
        blibli
            bloblo

Как объяснено на странице руководства bash:

If the -e option is given, interpretation of the following backslash-escaped characters is enabled.
[...]
              \a     alert (bell)
              \b     backspace
              \c     suppress further output
              \e
              \E     an escape character
              \f     form feed
              \n     new line
              \r     carriage return
              \t     horizontal tab
              \v     vertical tab
              \\     backslash
              \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal digits)
              \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
              \uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
              \UHHHHHHHH
                     the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)

3
21.07.2020, 21:11
2 ответа

Zenity предназначен для чтения двух строк, одной для индикатора выполнения и одной, начинающейся с " #" для текста выполнения:

for ((i=0;i<=100;i++));do
  echo "$i"                  # bar
  echo "#percent done $i"    # text
  sleep.1
done
| zenity --progress

Я предполагаю, что опция--bar записывает прогресс в stderr, но не закрывает его или не пишет символ новой строки в конце строки. Это блокирует зенит, ожидающий новой линии. Обходной путь состоит в том, чтобы напечатать новую строку в stderr, который по умолчанию является файловым дескриптором 2.

seq 1000 | parallel -j30 --bar '(echo {}; echo >&2; sleep 0.1)' \
    2> >(zenity --progress --auto-kill) | wc
3
18.03.2021, 23:19

Очевидно, zenityхочет, чтобы новая строка для Cancel работала.

GNU Parallel --barиспользует \rв своих выходных данных, что прекрасно работает для индикатора выполнения в zenity, но, что удивительно, не для кнопки Cancel.

Таким образом, одним из очевидных решений является замена \rна \nперед подачей на zenity, если вам нужна кнопка «Отмена» :

.
seq 1000 |
  parallel -j30 --bar '(echo {}; sleep 0.1)' 2> >(perl -pe 'BEGIN{$/="\r";$|=1};s/\r/\n/g' |
    zenity --progress --auto-kill) |
  wc

Менее очевидным решением является использование straceи трассировка того, что никогда не происходит:

seq 1000 |
  parallel -j30 --bar '(echo {};sleep 0.1)' 2> >(strace -e trace=creat zenity --progress --auto-kill) |
  wc

Я совершенно не понимаю, почему straceэто работает.

1
18.03.2021, 23:19

Теги

Похожие вопросы