在腳本或者程序運行時間較長時,為終端用戶提供反饋信息,表示腳本或程序在辛勤工作,是非常重要的。本文將介紹常見的兩種進度指示器(一系列原點和一條旋轉線)以及一些其他提供進度指示的工具。
1. 使用一系列原點來指示進度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#!/bin/bash
function
dots(){
seconds=${1:-5}
# print a dot every 5 seconds by default
while
true
do
sleep
$seconds
echo
-n
'.'
done
}
dots 10 &
BG_PID=$!
trap
"kill -9 $BG_PID"
INT
# Do the real job here
sleep
150
kill
$BG_PID
echo
|
dots函數每隔一段時間打印一個圓點,這個時間值可以通過第一個參數傳入,否則默認為5秒。在后台啟動dots函數之后,通過"$!"獲取dots的pid,然后開始執行耗時的工作,在工作執行完畢之后kill掉后台執行的dots。trap命令是為了防止用戶Ctrl_C中斷腳本執行的時候dots仍然在后台執行。
2. 使用一條旋轉線來表示進度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#!/bin/bash
function
rotate(){
INTERVAL=0.5
RCOUNT=
"0"
echo
-n
'Processing'
while
:
do
((RCOUNT = RCOUNT + 1))
case
$RCOUNT
in
1)
echo
-e
'-\b\c'
sleep
$INTERVAL
;;
2)
echo
-e
'\\\b\c'
sleep
$INTERVAL
;;
3)
echo
-e
'|\b\c'
sleep
$INTERVAL
;;
4)
echo
-e
'/\b\c'
sleep
$INTERVAL
;;
*) RCOUNT=0
;;
esac
done
}
rotate &
trap
"kill -9 $BG_PID"
INT
ROTATE_PID=$!
# Do the job here
sleep
15
kill
-9 $ROTATE_PID
echo
|
為了使用一條旋轉線來作為進度指示器,可以通過按順序逐個顯示/-\|然后重復這個過。為使這一字符序列無縫地顯示,需要對前一個字符退格顯示並刪除它,或者用一個新字符來覆蓋它,使得看起來好像一條線在旋轉。
3、使用pv顯示進度
pv(Pipe Viewer)可以顯示通過管道的內容的數據通過量、數據通過速度、已用時間、估計剩余時間(ETA)、通過百分比等信息。在使用的時候,可以將pv插在兩個進程的管道之間,並提供恰當的參數。比如為了查看tar備份的速度,可以用
1
|
tar
czf -
/path/to/some/directory/
* | pv > backup.
tar
.gz
|
為了查看cp的速度,可以用
1
|
file
=
/path/to/some/file
size=`
ls
-sk $
file
|
awk
'{print $1}'
` && pv -s ${size}k $
file
>
/desination/filename
|
4. 使用dialog顯示進度
dialog是一種在shell腳本里顯示對話框的工具,其提供的--gauge可以用來作為進度條使用,其中進度大小從標准輸入讀入。下面是一個簡單的例子:
1
|
for
i
in
$(
seq
0 10 100) ;
do
sleep
1;
echo
$i | dialog --gauge
"Please wait"
10 70 0;
done
|
下面的腳本提供對cp進度的顯示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/bin/bash
file
=$1
newfile=$2
filename=`
basename
$
file
`
if
[ -d $newfile ];
then
newfile=$newfile/$filename
fi
cp
$
file
$newfile &
CP_PID=$!
trap
'kill -9 $CP_PID'
INT
size_old=`stat -c
"%s"
$
file
`
size_new=`stat -c
"%s"
$newfile`
(
while
[ $size_new -lt $size_old ];
do
echo
"$size_new * 100 / $size_old"
|
bc
sleep
1
size_new=`stat -c
"%s"
$newfile`
done
) | dialog --title
"File Copy"
--gauge
"cp $file $newfile"
10 70 0
|
5. 另一種對cp提供進度顯示的方法
這種方法來自這里 ,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/bin/sh
cp_p()
{
strace
-q -ewrite
cp
--
"${1}"
"${2}"
2>&1 \
|
awk
'{
count += $NF
if
(count % 10 == 0) {
percent = count / total_size * 100
printf
"%3d%% ["
, percent
for
(i=0;i<=percent;i++)
printf
"="
printf
">"
for
(i=percent;i<100;i++)
printf
" "
printf
"]\r"
}
}
END { print
""
}
' total_size=$(stat -c '
%s'
"${1}"
) count=0
}
|