shell進(jìn)度條追蹤指令執(zhí)行時(shí)間的場(chǎng)景分析
最近一兩年,我經(jīng)手了不少與shell相關(guān)的工作。在這個(gè)過(guò)程中,我越發(fā)覺(jué)得shell腳本在完成具體任務(wù)的同時(shí),應(yīng)該再給用戶展示一個(gè)進(jìn)度條,用以提示當(dāng)前階段還需要多少時(shí)間才能完成。
linux中的不少軟件都有進(jìn)度條,比如yum的軟件安裝過(guò)程,docker的鏡像拉取過(guò)程。本想借鑒這些軟件的進(jìn)度條的實(shí)現(xiàn)方法,但其開(kāi)發(fā)語(yǔ)言大都不是shell,我就只好作罷。隨后,我在網(wǎng)上搜索shell進(jìn)度條的實(shí)現(xiàn)方法,而找到的大都是用for或while循環(huán)在控制臺(tái)上直接打印等號(hào)或箭頭,并在循環(huán)體中用sleep命令實(shí)現(xiàn)一個(gè)固定的停頓,因而進(jìn)度條完成的時(shí)間是固定的,而且在打印進(jìn)度條時(shí)也沒(méi)有實(shí)現(xiàn)具體任務(wù)。那種進(jìn)度條是完全沒(méi)有意義的。
于是,我就自己實(shí)現(xiàn)了一個(gè)shell進(jìn)度條,測(cè)試表明實(shí)現(xiàn)了既定目標(biāo)??梢宰粉欀噶畹膱?zhí)行時(shí)間。如果在預(yù)定用時(shí)之前完成,那么進(jìn)度條會(huì)接到通知,然后立刻跑完剩余進(jìn)度;如果指令的運(yùn)行用時(shí)超出預(yù)定時(shí)間,那么進(jìn)度條會(huì)在96%的地方等待指令跟上,然后再跑完剩余的4%。
本文中的進(jìn)度條可以應(yīng)用于大部分場(chǎng)景。不用修改進(jìn)度條函數(shù)的任何代碼,就可以直接使用。特別適合那些可預(yù)估指令執(zhí)行時(shí)間的場(chǎng)景。對(duì)于如下載、文件復(fù)制等可以準(zhǔn)確地計(jì)算出進(jìn)度數(shù)值的情況,也可以基本滿足,還可以參考本文的思路,修改進(jìn)度條函數(shù),進(jìn)而顯示精確的進(jìn)度數(shù)值。
代碼
代碼如下:
#!/bin/bash
progressBarTempPath=$(mktemp)
echo "0" >"$progressBarTempPath"
progressBar () {
local time=$1
local interval=1
if [[ "${time}" == *"s" ]]; then
interval=$(echo "scale=5;${time//s/}/60"|bc)
elif [[ "${time}" == *"m" ]]; then
interval=${time//m/}
else
echo "進(jìn)度條參數(shù)錯(cuò)誤"
return 1
fi
local nowNum=1
local str=''
local postfix=('/' '-' '\' '|')
while [ $nowNum -le 100 ]; do
local needEnd=`cat "$progressBarTempPath"`
local index=$((nowNum%4))
printf "[%-50s %-3d%% %c]\r" "$str" "$nowNum" "${postfix[$index]}"
nowNum=$((nowNum+1))
if [ $needEnd -eq 1 ]; then
sleep 0.1
else
if [ $nowNum -le 20 ] ; then
sleep $interval
elif [ $nowNum -gt 95 ];then
local nowNumCopy=$nowNum
while [ $needEnd -eq 0 ]; do
sleep $interval
local innerIndex=$(((nowNumCopy+1)%4))
printf "[%-50s %-3d%% %c]\r" "$str" "$nowNum" "${postfix[$innerIndex]} "
needEnd=$(cat "$progressBarTempPath")
nowNumCopy=$((nowNumCopy+1))
done
else
sleep $(echo "scale=5;${interval}/2"|bc)
fi
fi
if (($nowNum % 2 == 0)); then
str+='='
fi
done
printf "\n"
}
# 多線程調(diào)用進(jìn)度條函數(shù),參數(shù)表示預(yù)估的大概時(shí)間。參數(shù)中的s表示時(shí)間單位秒,還可以用m表分鐘。
progressBar 20s &
# 調(diào)用進(jìn)度條后,就是完成具體操作的代碼。
echo "模擬一個(gè)24秒執(zhí)行完成的任務(wù)。"
sleep 24
# 通知進(jìn)度條函數(shù)完成進(jìn)度
echo "1" >"$progressBarTempPath"
wait
使用說(shuō)明
使用非常簡(jiǎn)單,按照以下兩步操作即可。
- 將代碼中的第56、57行換成您實(shí)際需要執(zhí)行的命令。最好屏蔽其運(yùn)行過(guò)程中的輸出。
- 將代碼中第53行的方法調(diào)用參數(shù)
20s換成你預(yù)估的實(shí)際時(shí)間。
效果展示

到此這篇關(guān)于shell進(jìn)度條如何追蹤指令執(zhí)行時(shí)間的文章就介紹到這了,更多相關(guān)shell進(jìn)度條追蹤指令執(zhí)行時(shí)間內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
學(xué)習(xí)Linux網(wǎng)絡(luò)編程基本函數(shù)
這篇文章主要介紹了學(xué)習(xí)Linux網(wǎng)絡(luò)編程,網(wǎng)絡(luò)編程的一些基本函數(shù):也是實(shí)現(xiàn)tcp協(xié)議通訊的基本步驟,實(shí)現(xiàn)代碼在最后,IP需要修改為自己的IP,即可通信2021-08-08
Linux 下xargs命令詳解及xargs與管道的區(qū)別
在工作中經(jīng)常會(huì)接觸到xargs命令,特別是在別人寫的腳本里面也經(jīng)常會(huì)遇到,但是卻很容易與管道搞混淆,本篇會(huì)詳細(xì)講解到底什么是xargs命令,為什么要用xargs命令以及與管道的區(qū)別,本文通過(guò)實(shí)例給大家詳解,需要的的朋友參考下2017-04-04
shell腳本中一鍵部署zookeeper集群服務(wù)的方法
Zookeeper是一個(gè)開(kāi)源的分布式的,為分布式框架提供協(xié)調(diào)服務(wù)的Apache項(xiàng)目,這篇文章主要介紹了shell腳本一鍵部署zookeeper集群服務(wù)的方法,需要的朋友可以參考下2022-05-05
shell腳本無(wú)密碼登錄 expect的使用方法詳解
這篇文章主要介紹了shell腳本無(wú)密碼登錄 expect的使用方法詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-10-10
Shell腳本實(shí)現(xiàn)非法IP登陸自動(dòng)報(bào)警
這篇文章主要介紹了Shell腳本實(shí)現(xiàn)非法IP登陸自動(dòng)報(bào)警,本文實(shí)現(xiàn)非指定IP段登錄服務(wù)器時(shí)使用郵件報(bào)警,需要的朋友可以參考下2015-02-02

