網站首頁 編程語言 正文
最近一兩年,我經手了不少與shell相關的工作。在這個過程中,我越發覺得shell腳本在完成具體任務的同時,應該再給用戶展示一個進度條,用以提示當前階段還需要多少時間才能完成。
linux中的不少軟件都有進度條,比如yum的軟件安裝過程,docker的鏡像拉取過程。本想借鑒這些軟件的進度條的實現方法,但其開發語言大都不是shell,我就只好作罷。隨后,我在網上搜索shell進度條的實現方法,而找到的大都是用for或while循環在控制臺上直接打印等號或箭頭,并在循環體中用sleep命令實現一個固定的停頓,因而進度條完成的時間是固定的,而且在打印進度條時也沒有實現具體任務。那種進度條是完全沒有意義的。
于是,我就自己實現了一個shell進度條,測試表明實現了既定目標。可以追蹤指令的執行時間。如果在預定用時之前完成,那么進度條會接到通知,然后立刻跑完剩余進度;如果指令的運行用時超出預定時間,那么進度條會在96%的地方等待指令跟上,然后再跑完剩余的4%。
本文中的進度條可以應用于大部分場景。不用修改進度條函數的任何代碼,就可以直接使用。特別適合那些可預估指令執行時間的場景。對于如下載、文件復制等可以準確地計算出進度數值的情況,也可以基本滿足,還可以參考本文的思路,修改進度條函數,進而顯示精確的進度數值。
代碼
代碼如下:
#!/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 "進度條參數錯誤" 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" } # 多線程調用進度條函數,參數表示預估的大概時間。參數中的s表示時間單位秒,還可以用m表分鐘。 progressBar 20s & # 調用進度條后,就是完成具體操作的代碼。 echo "模擬一個24秒執行完成的任務。" sleep 24 # 通知進度條函數完成進度 echo "1" >"$progressBarTempPath" wait
使用說明
使用非常簡單,按照以下兩步操作即可。
- 將代碼中的第56、57行換成您實際需要執行的命令。最好屏蔽其運行過程中的輸出。
- 將代碼中第53行的方法調用參數
20s
換成你預估的實際時間。
效果展示
原文鏈接:https://blog.csdn.net/monarch91/article/details/124788554
相關推薦
- 2022-10-09 Xshell連接不上虛擬機的解決辦法匯總_Linux
- 2023-12-09 【設計模式-3.1】結構型——外觀模式
- 2022-09-16 Python封裝zabbix-get接口的代碼分享_python
- 2022-11-06 SQL?Server?Reporting?Services?匿名登錄的問題及解決方案_MsSql
- 2024-02-16 ReentrantLock相較于synchronized的區別---鎖超時(源碼理解)
- 2022-09-20 android原生實現多線程斷點續傳功能_Android
- 2022-11-22 Android?RecyclerView使用入門介紹_Android
- 2023-02-03 c語言統計素數之和的實例_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支