Создайте индикатор выполнения в ударе

Как я могу создать индикатор выполнения с ударом?

Это - мой сценарий:

 #!/bin/bash
 pass='number1 number12 number13 number14 number15 number16'
 chk='number14'
 for i in $pass ; do
 if [ "$i" == "$chk" ]; then
 echo ' Found ^_^'
 else
 echo 'loading 50%'
 fi
 done

Я хочу заменить echo 'loading 50%' с чем-либо для создания индикатора выполнения.

14
задан 18 March 2016 в 21:47

5 ответов

Вот еще один подход, использующий ansi escape codes:

#!/bin/bash

pass='number1 number2 number 3 number4 number12 number13 number14 number15 number16'
chk='number15'
result="Not Found!"

echo
echo -n "Working... "
echo -ne "\033[1;32m\033[7m\033[?25l"

for i in $pass ; do
   sleep .4s
   if [ "$i" == "$chk" ]; then
      result="  Found ^_^"
      break
   else
      echo -n " "
   fi
done

echo -ne "\r\033[0m\033[K\033[?25h"
echo $result
echo
1
ответ дан 23 November 2019 в 03:14

Вы можете использовать zenity для создания простых диалоговых окон GTK. Одной из доступных опций является диалоговое окно индикатора выполнения.

Вы создаете такое окно, используя zenity --progress . Чтобы сделать его полезным, вы должны указать дополнительную информацию, добавив некоторые из приведенных ниже параметров (отрывок из man zenity ):

   Progress options
   --text=STRING
          Set the dialog text
   --percentage=INT
          Set initial percentage
   --auto-close
          Close dialog when 100% has been reached
   --auto-kill
          Kill parent process if cancel button is pressed
   --pulsate
          Pulsate progress bar
   --no-cancel
          Hides the cancel button

Есть два режима:

  • пульсирующий : индикатор выполнения пульсирует, просто указывает на то, что что-то работает, но ничего не говорит о прогрессе. Это можно сделать, установив параметр - pulsating .

  • manual : вы должны передать текущий процент прогресса в стандартный ввод команды zenity , чтобы обновить индикатор выполнения .
    Пример для этого может выглядеть так, как показано ниже. Обратите внимание, что предыдущие команды сгруппированы в подоболочку, поэтому весь вывод перенаправляется в диалоговое окно zenity , а не только в последнюю команду:

     (echo 10; sleep 2; echo 20; sleep  2; эхо 50; сон 2) |  ум - прогресс
     
6
ответ дан 23 November 2019 в 03:14

Этот код сделает это и не требует ничего (кроме bash, конечно). Он печатает знаки # , как вы спрашивали в своем комментарии:

pass='number1 number12 number13 number14 number15 number16'
chk='number14'
passarr=($pass)
lenProgressBar=${#passarr[@]}

echo -n '['
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -n '-'
    ((i++))
done

echo -n ']'
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -e -n '\b'
    ((i++))
done

echo -e -n '\b'
for i in $pass ; do
    if [ "$i" = "$chk" ]; then
        echo -e '#\nFound ^_^'
        break
    else
        echo -n '#'
    fi
done

Однако, если вам нужно многое проверить, это просто заполнит ваш экран знаками # . Чтобы решить эту проблему, попробуйте следующий код:

lenProgressBar=5
pass='number1 number12 number13 number14 number15 number16'
chk='number14'
passarr=($pass)
lenPass=${#passarr[@]}

if [ $lenProgressBar -gt $lenPass ]; then
    lenProgressBar=lenPass
elif [ $lenProgressBar -lt 1 ]; then
    lenProgressBar=1
fi

let "chksForEqualsPrint = $lenPass / $lenProgressBar"
echo -n '['
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -n '-'
    ((i++))
done

echo -n ']'
i=0

while [ $i -lt $lenProgressBar ]; do
    echo -e -n '\b'
    ((i++))
done

echo -e -n '\b'
n=1

for i in $pass ; do
    if [ "$i" = "$chk" ]; then
        echo -e '\nFound ^_^'
        break
    else
        if [ $n -eq $chksForEqualsPrint ]; then
            echo -n '#'
            n=1
        else
            ((n++))
        fi
    fi
done

Измените 5 в первой строке ( lenProgressBar = 5 ) на длину, которая должна быть у вашего индикатора выполнения. Для печати знака # с индикаторами выполнения меньшей длины потребуется больше времени, чем с индикаторами большей длины,но не позволяйте длине индикатора выполнения превышать размер вашего экрана; это не сработает, если вы это сделаете. (Это не позволит вам использовать индикатор выполнения больше, чем количество проверяемых элементов, или меньше 1)

5
ответ дан 23 November 2019 в 03:14

whiptail предустановлен в Ubuntu и многих других дистрибутивах и будет показывать полноэкранный (но все еще терминальный) прогресс. элементы.

dialog является расширенным набором whiptail , поэтому этот пример будет одинаково хорошо работать с обоими. Он предоставляет более продвинутые элементы пользовательского интерфейса, поэтому он может пригодиться, если вы ищете взаимодействие с пользователем, такое как средства выбора файлов и формы, но у него есть недостаток, заключающийся в том, что он не предустановлен во многих системах.

whiptail

dialog

for i in $(seq 1 100)
do
    sleep 0.1 
    echo $i
done | whiptail --title 'Test script' --gauge 'Running...' 6 60 0

Обратите внимание, что вывод сценария интерпретируется в процентах, поэтому вам, возможно, придется соответствующим образом скорректировать вывод.

Whiptail и Dialog также позволяют изменять текст во время выполнения с помощью довольно загадочного синтаксиса:

phases=( 
    'Locating Jebediah Kerman...'
    'Motivating Kerbals...'
    'Treating Kessler Syndrome...'
    'Recruiting Kerbals...'
)   

for i in $(seq 1 100); do  
    sleep 0.1

    if [ $i -eq 100 ]; then
        echo -e "XXX\n100\nDone!\nXXX"
    elif [ $(($i % 25)) -eq 0 ]; then
        let "phase = $i / 25"
        echo -e "XXX\n$i\n${phases[phase]}\nXXX"
    else
        echo $i
    fi 
done | whiptail --title 'Kerbal Space Program' --gauge "${phases[0]}" 6 60 0

pv показывает ход выполнения файл или поток, передаваемый через него. Однако его нельзя (легко?) Использовать для отображения хода выполнения пользовательской операции, такой как цикл. Он разработан специально для потоков.

$ head -c 1G < /dev/urandom | pv -s 1G > /dev/null
 277MB 0:00:16 [17.4MB/s] [========>                           ] 27% ETA 0:00:43

Некоторые реальные примеры, когда pv пригодится:

# progress while importing a DB dump
pv mybigfile.sql | mysql -uroot -p dbname

# importing straight from a remote server
ssh user@server 'cat mybigfile.sql.gz' | pv | gzip -cd | mysql -uroot -p dbname

# taking a snapshot of a btrfs partition
btrfs send /snapshots/$date | pv | btrfs receive /mnt/backup/root

Я не знаю команд, которые отображают однострочные индикаторы выполнения в стиле ] pv или wget , но существует множество простых сценариев Bash / Perl / sed, которые добавят эту функциональность, о чем здесь рассказали другие.

14
ответ дан 23 November 2019 в 03:14

Из Stack Overflow

мне нужен был индикатор выполнения, который поместился бы во всплывающее всплывающее сообщение ( notify-send ) для представления уровня громкости телевизора. Недавно я писал музыкальный проигрыватель на python, и телевизионное изображение в большинстве случаев отключено.

Пример вывода из терминала

test_progress_bar3.gif


Bash-скрипт

#!/bin/bash

# Show a progress bar at step number $1 (from 0 to 100)


function is_int() { test "$@" -eq "$@" 2> /dev/null; } 

# Parameter 1 must be integer
if ! is_int "$1" ; then
   echo "Not an integer: ${1}"
   exit 1
fi

# Parameter 1 must be >= 0 and <= 100
if [ "$1" -ge 0 ] && [ "$1" -le 100 ]  2>/dev/null
then
    :
else
    echo bad volume: ${1}
    exit 1
fi

# Main function designed for quickly copying to another program 
Main () {

    Bar=""                      # Progress Bar / Volume level
    Len=25                      # Length of Progress Bar / Volume level
    Div=4                       # Divisor into Volume for # of blocks
    Fill="▒"                    # Fill up to $Len
    Arr=( "▉" "▎" "▌" "▊" )     # UTF-8 left blocks: 7/8, 1/4, 1/2, 3/4

    FullBlock=$((${1} / Div))   # Number of full blocks
    PartBlock=$((${1} % Div))   # Size of partial block (array index)

    while [[ $FullBlock -gt 0 ]]; do
        Bar="$Bar${Arr[0]}"     # Add 1 full block into Progress Bar
        (( FullBlock-- ))       # Decrement full blocks counter
    done

    # If remainder zero no partial block, else append character from array
    if [[ $PartBlock -gt 0 ]]; then
        Bar="$Bar${Arr[$PartBlock]}"
    fi

    while [[ "${#Bar}" -lt "$Len" ]]; do
        Bar="$Bar$Fill"         # Pad Progress Bar with fill character
    done

    echo Volume: "$1 $Bar"
    exit 0                      # Remove this line when copying into program
} # Main

Main "$@"

Тестовый bash-скрипт

Используйте этот скрипт для тестирования индикатор выполнения в терминале.

#!/bin/bash

# test_progress_bar3

Main () {

    tput civis                              # Turn off cursor
    for ((i=0; i<=100; i++)); do
        CurrLevel=$(./progress_bar3 "$i")   # Generate progress bar 0 to 100
        echo -ne "$CurrLevel"\\r            # Reprint overtop same line
        sleep .04
    done
    echo -e \\n                             # Advance line to keep last progress
    echo "$0 Done"
    tput cnorm                              # Turn cursor back on
} # Main

Main "$@"

TL; DR

В этом разделе подробно описано, как notify-send используется для быстрого спама всплывающих всплывающих сообщений на рабочий стол. Это необходимо, поскольку уровень громкости может меняться много раз в секунду, а поведение пузырькового сообщения по умолчанию заключается в том, что сообщение остается на рабочем столе в течение многих секунд.

Пример всплывающего всплывающего сообщения

tvpowered.gif

Всплывающее всплывающее сообщение bash-код

От сценарий над функцией main был скопирован в новую функцию с именем VolumeBar в существующем сценарии bash с именем tvpowered . Команда exit 0 в скопированной функции main была удалена.

Вот как ее вызвать и сообщить команде Ubuntu notify-send , что мы будем рассылать спам всплывающее всплывающее сообщение:

VolumeBar $CurrVolume
# Ask Ubuntu: https://askubuntu.com/a/871207/307523
notify-send --urgency=critical "tvpowered" \
    -h string:x-canonical-private-synchronous:volume \
    --icon=/usr/share/icons/gnome/48x48/devices/audio-speakers.png \
    "Volume: $CurrVolume $Bar"

Это новая строка, которая сообщает notify-send немедленно заменить последнее всплывающее всплывающее окно:

-h string:x-canonical-private-synchronous:volume \

том группирует всплывающие всплывающие сообщения вместе, а новые сообщения немедленно в этой группе заменяет предыдущий. Вы можете использовать что угодно вместо тома .

0
ответ дан 5 January 2021 в 22:43

Другие вопросы по тегам:

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