在Linux执行费时操作(如tar)时显示进度条,以不至于让用户觉得程序卡死了。
效果
文本进度条
结束后:
图形化字符进度条
文本进度条怎么做
进度条实现
网上有一些老六会说要下载一些工具,如:pv。这就很不优雅(当你的脚本要给人做安装包的时候,你自己就是安装包,你还要求别人先装一些工具才能看进度条,是不是很不优雅),我懒得搞这种,有这闲功夫不如自己整一个,反正也没几行代码。
老规矩,来最简单的,shell代码(这里绝对相信用户输入,所以不做参数校验。好吧其实是我懒得校验):
#!/bin/bash # 打印进度条 # 参数1 label 标签,显示在最左边 # 参数2 current 当前进度,0~100的整数 # 参数3 tip 提示信息,显示在最右边(默认为当前进度) # 参数4 length 进度条长度,整数,字符个数(默认为50) # 参数5 chr 填充字符,进度条填充用(默认为=) # 显示如: # label[======== ]tip print_gauge() { local label=$1 # 标签,显示在最左边 local current=$2 # 当前进度,0~100的整数 local tip=${3:-" $current%%"} # 提示信息,显示在最右边(默认为当前进度) local length=${4:-50} # 进度条长度,整数,字符个数(默认为50) local chr=${5:-=} # 填充字符,进度条填充用(默认为=) local cur_chr_n=$((current * length / 100)) printf "\r${label}[" local i for ((i = 0; i < cur_chr_n; i++)); do printf "$chr" done for ((i = cur_chr_n; i < length; i++)); do printf " " done printf "]${tip}" } # 读入标准输入的方式统计进度条 # 参数1 label 标签,显示在最左边 # 参数2 size 标准输入流总大小 # 参数3 over_tip 结束时的提示(默认为100%) # 参数4 length 进度条长度,整数,字符个数(默认为50) # 参数5 chr 填充字符,进度条填充用(默认为=) dd_gauge() { local label=$1 # 标签,显示在最左边 local size=$2 # 标准输入流总大小 local over_tip=${3:-" 100%%"} # 结束时的提示(默认为100%) local length=${4:-50} # 进度条长度,整数,字符个数(默认为50) local chr=${5:-=} # 填充字符,进度条填充用(默认为=) local count=0 local current local tip="" while ((count < size)); do dd bs=512 count=10000 2>/dev/null ((count += 5120000)) ((current = count * 100 / size)) ((current > 100)) && current=100 [ "$current" == "100" ] && tip=$over_tip print_gauge "$label" "$current" "$tip" "$length" "$chr" >&2 done echo >&2 } # 对dd_gauge封装一层,自动计算文件大小 # 参数1 label 标签,显示在最左边 # 参数2 filename 文件名 # 参数3 over_tip 结束时的提示(默认为100%) # 参数4 length 进度条长度,整数,字符个数(默认为50) # 参数5 chr 填充字符,进度条填充用(默认为=) dd_gauge_from_file() { local label=$1 # 标签,显示在最左边 local filename=$2 # 文件名 local over_tip=${3:-" 100%%"} # 结束时的提示(默认为100%) local length=${4:-50} # 进度条长度,整数,字符个数(默认为50) local chr=${5:-=} # 填充字符,进度条填充用(默认为=) local size=$(stat -c %s -- "$filename") dd_gauge "$label" "$size" "$over_tip" "$length" "$chr" <"$filename" } # 读入标准输入的方式按需求显示进度条 # 参数1 label 标签,显示在最左边 # 参数2 over_tip 结束时的提示(默认为当前进度) # 参数3 length 进度条长度,整数,字符个数(默认为50) # 参数4 chr 填充字符,进度条填充用(默认为=) show_gauge() { local label=$1 # 标签,显示在最左边 local over_tip=$2 # 结束时的提示(默认为当前进度) local length=${3:-50} # 进度条长度,整数,字符个数(默认为50) local chr=${4:-=} # 填充字符,进度条填充用(默认为=) local current local tmp while read current; do tmp=$current print_gauge "$label" "$current" "" "$length" "$chr" >&2 done print_gauge "$label" "$tmp" "$over_tip" "$length" "$chr" >&2 echo >&2 }
进度条调用
假设上一节进度条实现的shell代码保存为gauge.sh
如果是读取文件操作的(如计算md5或者解压tar之类的操作)
# 这里演示计算md5的,假设要计算md5的文件为xxx . gauge.sh dd_gauge_from_file "计算md5进度: " "xxx" "计算完毕" | md5sum
效果:
计算完毕后:
实际上 dd_gauge_from_file a b c d e 等价于 dd_gauge a $(stat -c %s b) c d e
如果是读取输出流的(如三剑客解析后再用其他工具解析之类的操作)
# 这里演示从简,假设就是计算dd后的md5
. gauge.sh
dd if=/dev/zero bs=1M count=1000 2>/dev/null | dd_gauge "dd zero md5: " "$((1024 * 1024 * 1000))" | md5sum
如果是自定义进度的(如一系列操作,到哪步规定是20%,哪步规定的50%之类的)
# 这里演示从简,就随便打打进度 . gauge.sh (echo 0; sleep 10; echo 20; sleep 10; echo 50; sleep 10; echo 90; sleep 10; echo 100) | show_gauge "自定义进度: "
实际上你要自定义进度的操作应该是类似这样的:
. gauge.sh ( # 做一些创建配置的操作 create_config # Linux里面没有这个命令的,这只是假设你做创建配置的操作 echo 10 # 配置创建好了,可以认为进度到 10% 了,这些都是可以自定义的 # 做一些复制文件的操作 do_copy_file echo 50 # 文件复制完了,可以认为进度到 50% 了 # 创建一些软链接 do_create_link echo 100 ) | show_gauge "进度: "
图形化字符进度条怎么做
这个其实老简单了,直接用现成的whiptail或者dialog。
一般来说,标准centos(即使是最简安装)都会自带whiptail工具,而ubuntu有些分支版本可能自带的是dialog(从而没有自带whiptail)。所幸,whiptail和dialog的用法差不多,所以可以这样:
my_dialog() { DIALOG="" type whiptail >/dev/null 2>&1 && DIALOG="whiptail" type dialog >/dev/null 2>&1 && DIALOG="dialog" [ -n "$DIALOG" ] && "$DIALOG" "$@" }
给代码加点保护措施。
dialog显示进度条的方法为:
( do_something echo 10 # 进度可自定义 do_something echo 20 # 进度可自定义 ... echo 100 # 进度可自定义,最后没到 100% 也可以 ) | dialog --gauge 进度 0 50 0 # 其中dialog第一个参数为类型,--gauge就表示进度条显示的东西 # 如果第一个参数为--gauge则: # 第二个参数为显示的内容 # 第三个参数为高度,0表示自适应 # 第四个参数为宽度 # 第五个参数为初始进度 # whiptail对进度条而言,参数和dialog差不多 # 如果不确定环境上有dialog还是whiptail,可以用保护措施,用my_dialog
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章