小编典典

如何在 shell 脚本中添加进度条?

all

在 bash 或 *NIX 中的任何其他 shell 中编写脚本时,在运行需要几秒钟以上的命令时,需要一个进度条。

例如,复制一个大文件,打开一个大 tar 文件。

您推荐哪些方式向 shell 脚本添加进度条?


阅读 146

收藏
2022-03-10

共1个答案

小编典典

我需要一个适合弹出气泡消息 ( 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;博士

本节详细介绍如何notify-send将垃圾邮件弹出气泡消息快速发送到桌面。这是必需的,因为音量级别可以在一秒钟内更改多次,并且默认的气泡消息行为是让消息在桌面上停留数秒。

示例弹出气泡消息

电视供电的.gif

弹出气泡消息 bash 代码

从上面的脚本中,该main函数被复制到一个VolumeBar名为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 \

volume将弹出气泡消息组合在一起,该组中的新消息立即替换以前的消息。您可以使用anything而不是volume.

2022-03-10