一、進度條原理
進度條的的動態增長是利用人的視覺短暫停留效果的,不斷從輸出緩衝區刷新出相同的內容,在肉眼看來進度條在不斷的增長。
1、顯示問題:
因爲不需要多行顯示,只需刷新當前進度 ,那麼輸出時只需要回車‘\r’,不需要換行‘\n’
2、關於緩衝區:
linux下的每一個進程會維護一個print/scanf的緩衝區,對於緩衝區而言,緩衝區有一個概念叫做緩衝方式,就是說達到一定的方式,緩衝區的內容纔會被刷新。
標C庫函數自帶緩衝區 ,常見的三種緩衝方式:
(1)行緩衝:遇到”\n”,就會刷新緩衝區
(2)全緩衝:把緩衝區寫滿,再進行刷新緩衝區
(3)無緩衝:系統調用函數無緩衝區(如:write)
默認情況下,一般採用行緩衝模式
當程序退出緩衝區自動刷新,也就是一個進程結束的時候,當使用scanf也會刷新。
所以,爲了每次進行打印每行的內容,我們需要採用強制刷新緩衝區,這裏有一個函數fflush()。
二、進度條的兩種實現
1、用C語言實現
這裏採用for循環打印的方式實現:
(1)程序代碼:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4
5 int main()
6 {
7 char buf[102]={0};//因爲1—100是101個數,最後還要存一個‘\0’,所以大 小爲102
8 char *str="-\|/";
9 int i=0;
10 for(;i<=100;++i)
11 {
12 printf("\033[034m[%-100s],[%d%%],[%c]\r",buf,i,str[i%4]);
13
14 fflush(stdout);
15 usleep(20000);
16 buf[i]='#';
17 }
18 printf("\n");
19 return 0;
20 }
運行結果:
2、用shell腳本語言實現彩色進度條
在用shell編寫彩色進度條的時候,我們需要了解:
設定printf在終端輸出字體的顏色:
終端字符的顏色是用轉義序列進行控制,是文本模式下的系統顯示功能,和具體的語言無關。
轉義序列是以 ESC 開頭,可以用 \033 完成相同的工作(ESC 的 ASCII 碼用十進制表示就是 27, = 用八進制表示的 33)。
- 格式是:\033[顯示方式;前景色;背景色m
類別 | 顏色 |
---|---|
顯示方式 | 0(默認值)、1(高亮)、22(非粗體)、4(下劃線)、24(非下劃線)、5(閃爍)、25(非閃爍)、7(反顯)、27(非反顯) |
前景色 | 30(黑色)、31(紅色)、32(綠色)、 33(黃色)、34(藍色)、35(洋紅)、36(青色)、37(白色) |
背景色 | 40(黑色)、41(紅色)、42(綠色)、 43(黃色)、44(藍色)、45(洋紅)、46(青色)、47(白色) |
代碼實現:
實現簡單的彩色進度條:
1 #!/bin/bash
2
3 i=0
4 b=""
5 array=('-' '\\' '|' '/')
6
7 while [ $i -le 100 ]
8 do
9 let idx=i%4
10 printf "\e[31m\033[40m[%-100s]\e[32m\033[47m [%d%%] \e[30m \033[47m [%c] \e[0m\r" "$b" "$i" "${array[$idx]}"
11 b+='#'
12 usleep 200000
13 let i++
14 done
運行結果:
改進版:
1 #!/bin/bash
2
3 i=0
4 str=""
5 array=("\\" "|" "/" "-")
6 while [ $i -le 100 ]
7 do
8 let idx=i%4
9 if [ $i -le 20 ]
10 then
11 let color=44
12 let bg=34
13 elif [ $i -le 50 ]
14 then
15 let color=43
16 let bg=31
17 else
18 let color=42
19 let bg=33
20
21 fi
22 printf "\033[${color};${bg}m%-s\033[0m [%d%%] [%c]\r" "$str" "$i" "${array[$idx]}"
23
24 usleep 300000
25 let i++
26 str+="#"
27 done
28 printf "\n"
運行結果:
這個進度條在不同的區間顏色不盡相同。