Как я могу создать индикатор выполнения с ударом?
Это - мой сценарий:
#!/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%'
с чем-либо для создания индикатора выполнения.
Вот еще один подход, использующий 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
Вы можете использовать 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) | ум - прогресс
Этот код сделает это и не требует ничего (кроме 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)
whiptail
предустановлен в Ubuntu и многих других дистрибутивах и будет показывать полноэкранный (но все еще терминальный) прогресс. элементы.
dialog
является расширенным набором whiptail
, поэтому этот пример будет одинаково хорошо работать с обоими. Он предоставляет более продвинутые элементы пользовательского интерфейса, поэтому он может пригодиться, если вы ищете взаимодействие с пользователем, такое как средства выбора файлов и формы, но у него есть недостаток, заключающийся в том, что он не предустановлен во многих системах.
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, которые добавят эту функциональность, о чем здесь рассказали другие.
мне нужен был индикатор выполнения, который поместился бы во всплывающее всплывающее сообщение ( notify-send
) для представления уровня громкости телевизора. Недавно я писал музыкальный проигрыватель на python, и телевизионное изображение в большинстве случаев отключено.
#!/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 "$@"
Используйте этот скрипт для тестирования индикатор выполнения в терминале.
#!/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 "$@"
В этом разделе подробно описано, как notify-send
используется для быстрого спама всплывающих всплывающих сообщений на рабочий стол. Это необходимо, поскольку уровень громкости может меняться много раз в секунду, а поведение пузырькового сообщения по умолчанию заключается в том, что сообщение остается на рабочем столе в течение многих секунд.
От сценарий над функцией 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 \
том
группирует всплывающие всплывающие сообщения вместе, а новые сообщения немедленно в этой группе заменяет предыдущий. Вы можете использовать что угодно
вместо тома
.