总结

总结

如何使用 bash 创建进度条?

这是我的脚本:

 #!/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%'用任何东西来替换以创建进度条。

答案1

whiptail预装在 Ubuntu 和许多其他发行版上,并将显示全屏(但仍然基于终端)的进度元素。

dialog是 的超集whiptail,因此本示例对两者都同样适用。它确实提供了更高级的 UI 元素,因此如果您正在寻找文件选择器和表单等用户交互,它可能会派上用场,但它的缺点是许多系统上没有预装。

鞭尾

对话

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 脚本可以添加该功能,正如其他人在这里分享的那样。

答案2

您可以使用它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

  • 手动的:您必须将当前进度百分比通过管道传输到zenity命令的标准输入以更新进度条。
    此示例如下所示。请注意,前面的命令被分组到子 shell 中,以便所有输出都重定向到对话框zenity,而不仅仅是最后一个命令的输出:

    (echo 10; sleep 2; echo 20; sleep 2; echo 50; sleep 2) | zenity --progress
    

答案3

这段代码可以完成这个任务,并且不需要任何东西(当然,除了 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 的进度条)

答案4

堆栈溢出

我需要一个适合弹出气泡消息 ( notify-send) 的进度条来表示电视音量级别。最近我一直在用 Python 编写音乐播放器,电视画面大部分时间都是关闭的。

终端输出示例

测试进度条3.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 "$@"

总结

本节详细介绍了如何notify-send使用 来快速向桌面发送弹出气泡消息。这是必需的,因为音量级别每秒可以改变多次,并且默认的气泡消息行为是消息在桌面上停留数秒。

弹出气泡消息示例

电视供电.gif

弹出气泡消息 bash 代码

从上面的脚本中,将函数复制到现有 bash 脚本中main名为 的新函数中。复制函数中的命令已被删除。VolumeBartvpoweredexit 0main

以下是如何调用它并让 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 \

volume将弹出气泡消息分组在一起,此组中的新消息立即替换前一个。您可以使用anything代替volume

相关内容