在本文中,我们将详细介绍如何在Shell脚本中添加进度条。通过计算进度和显示进度条,可以改善用户体验,让用户了解任务的完成情况。
文章目录
进度条是一个图形化的界面元素,它用于表示一个操作的完成进度。它通常由两部分组成:一个表示总进度的背景条,和一个表示当前进度的填充条。填充条的长度相对于背景条的长度表示了操作的完成比例。
在 Shell 脚本中,我们可以使用文本字符来模拟进度条的效果。例如,我们可以使用等号=
来表示填充条,使用空格来表示背景条,然后使用方括号 []
来包围这些字符,创建出一个文本进度条的效果。以下是一个示例:Progress: [======= ]
在这个示例中,进度条的总长度是 10,当前的进度是 7,所以我们使用了 7 个等号和 3 个空格来表示这个进度。
在设计进度条时,我们需要考虑以下几个因素:
echo
和 printf
创建基本进度条,使用 tput
改善进度条的视觉效果,使用 trap
捕获用户中断,或者使用 pv
和 rsync
命令等。echo
和[printf](https://www./2021/bash-printf-ming-ling.html "printf")
命令来创建一个简单的进度条。以下是一个示例:#!/bin/bash
total=10
for ((i=0;i<=total;i++)); do
printf "\r[%-10s] %d%%" $(repeat '#' $i) $(($i * 10))
sleep 1
done
echo
在这个示例中,我们创建了一个总长度为10的进度条。printf
命令用于打印进度条,其中%-10s
表示进度条的长度,%d%%
表示完成的百分比。repeat '#' $i
是一个函数,用于重复打印#
字符,表示已完成的进度。sleep 1
用于模拟工作进度。tput
命令可以用于改善终端输出的视觉效果。我们可以使用tput
命令来改变进度条的颜色,或者清除进度条。以下是一个示例:#!/bin/bash
total=10
for ((i=0;i<=total;i++)); do
printf "\r\033[0K[%-10s] %d%%" $(repeat '#' $i) $(($i * 10))
sleep 1
done
echo
在这个示例中,我们使用了\033[0K
来清除当前行的内容,然后再打印新的进度条。这样可以确保进度条在更新时不会出现重叠。[trap](https://www./2023/bash-trap.html "trap")
命令来捕获这些中断,并在脚本结束时清理进度条。以下是一个示例:#!/bin/bash
trap 'printf "\n"; stty echo; exit' INT
total=10
for ((i=0;i<=total;i++)); do
printf "\r\033[0K[%-10s] %d%%" $(repeat '#' $i) $(($i * 10))
sleep 1
done
echo
在这个示例中,我们添加了一个trap
命令,用于捕获INT
信号,这个信号通常由用户按下Ctrl+C
产生。当捕获到这个信号时,我们打印一个新行,然后退出脚本。这样可以确保即使用户中断脚本的执行,进度条也能被正确的清理。pv
是 "pipe viewer" 的缩写,可以监视通过管道传输数据的进度。如果要传输/压缩/解压缩大文件,可以使用 pv
来显示进度条。例如:pv largefile.tar | tar x
在这个示例中,我们使用 pv
来监视 largefile.tar
文件的解压进度。[rsync](https://www./2021/linux-rsync-command.html "rsync")[Shell脚本](/tag/shell "Shell脚本")
提供了内置的进度展示功能,可以使用 --progress
选项来显示文件的同步进度。例如:rsync --progress sourcefile destinationfile
在这个示例中,我们使用 rsync
的 --progress
选项来查看 sourcefile
同步到 destinationfile
的进度。printf
命令来输出进度条,然后用 carriage return (\r
) 来覆盖同一行的内容,从而创建进度条的动态效果。以下是一个创建自定义进度条的基本示例:
#!/bin/bash
# 定义总的进度
total=100
# 循环,模拟任务进度
for ((i=1;i<=total;i++)); do
# 使用 printf 输出进度条,\r 覆盖同一行内容
printf "\rProgress: [%-100s] %d%%" $(printf '%.0s#' $(seq -s '' $i)) $i
# 模拟任务进度,每次循环 sleep 0.1 秒
sleep 0.1
done
# 输出换行,结束进度条
echo
在这个示例中,我们首先定义了一个变量 total
来表示任务的总进度。然后,我们使用一个 for 循环来模拟任务的进度。在每次循环中,我们使用 printf
命令来输出进度条,并使用 \r
来覆盖同一行的内容,从而创建出动态的进度条效果。这个进度条的长度是 100,表示的是任务的完成百分比。我们使用 printf '%.0s#' $(seq -s '' $i)
来输出一个由 #
组成的字符串,字符串的长度等于当前的进度。然后,我们使用 sleep 0.1
来模拟任务的进度。最后,当任务完成时,我们输出一个换行符,以结束进度条。这样,我们就创建了一个简单的自定义进度条。