当前位置:   article > 正文

Linux|shell编程|拷贝大文件之显示进度条_shell显示复制的进度

shell显示复制的进度

前言:

Linux由于自身并不是一个图形化的界面,因此,命令行是它的一个基础交互模式,而我们有的时候需要进度条来让程序运行的更加美观,更加直观,例如,一些比较消耗io的操作,文件拷贝,比如某个文件十几G甚至上百G,需要拷贝到本机的其它分区,那么,一个直观的进度条就十分有用了,可以让我们大致估算出多少时间拷贝完成,从而进行下一步的工作。

那么,本文将以一个10G的文件拷贝为例,输出一个按实际拷贝进度来显示的进度条。

一,

测试文件的准备

time命令统计dd命令的执行时间,可以看到用时1分钟6秒,硬盘速度161M每秒。

我的硬盘速度还算可以的

  1. [root@centos61 ~]# time dd if=/dev/zero of=Demofile bs=100M count=100
  2. 100+0 records in
  3. 100+0 records out
  4. 10485760000 bytes (10 GB) copied, 65.3247 s, 161 MB/s
  5. real 1m5.869s
  6. user 0m0.001s
  7. sys 0m13.644s
  8. [root@centos61 ~]# ls -alh Demofile
  9. -rw-r--r--. 1 root root 9.8G May 27 17:41 Demofile

二,

带实际拷贝进度的进度条的shell脚本(本文暂定该脚本名称为copyfile.sh):

  1. #!/bin/bash
  2. SOURCE=$1
  3. TARGET=$2
  4. CP=cp
  5. $CP "$SOURCE" "$TARGET" &
  6. CPID=$!
  7. trap "onCtrlC" INT
  8. function onCtrlC () {
  9. #捕获CTRL+C,当脚本被ctrl+c的形式终止时同时终止程序的后台进程
  10. kill -9 ${isalive} ${CPID}
  11. echo
  12. echo 'Ctrl+C is captured,拷贝已停止'
  13. exit 1
  14. }
  15. isalive(){
  16. out=`ps -p $1 2> /dev/null`
  17. return $?
  18. }
  19. while 2>1; do
  20. { SSIZE=`/bin/ls -l $SOURCE | gawk "{print \\\$5}"`
  21. if [ -f $TARGET ]; then
  22. TSIZE=`/bin/ls -l $TARGET | gawk "{print \\\$5}"`
  23. else
  24. TSIZE="0"
  25. fi
  26. PERCENT=`echo "scale=2; $TSIZE/$SSIZE*100" | bc -l`
  27. RATE=`echo "scale=0; 63*$PERCENT/100" | bc -l`
  28. BLUE="\\033[3;44m"
  29. NORMAIL="\\033[0;39m"
  30. BAR=$BLUE
  31. i=0
  32. while [ $i -le 62 ]; do
  33. [ $i = $RATE ] && BAR=$BAR"\\033[7;39m"
  34. BAR=$BAR" "
  35. let i=$i+1
  36. done
  37. BAR=$BAR$NORMAIL
  38. echo -en "\r$BAR ${PERCENT}%"
  39. if ! isalive "$CPID"; then echo -en "\n"; exit; fi
  40. sleep 1
  41. }
  42. done

脚本运行效果:

  1. [root@centos61 ~]# bash copyfile.sh Demofile Demofile-bak
  2. 14.00%^C
  3. Ctrl+C is captured,拷贝已停止

此时到百分之14的时候按ctrl+c停止了,我们可以核对一下目标文件是否是源文件的百分之14:

可以计算出1.5除以9.8确实是百分之14

  1. [root@centos61 ~]# ls -alh Demofile*
  2. -rw-r--r--. 1 root root 9.8G May 27 17:41 Demofile
  3. -rw-r--r--. 1 root root 1.5G May 27 18:25 Demofile-bak

 shell脚本完美运行!!!!!!

完整运行:

  1. [root@centos61 ~]# time bash copyfile.sh Demofile Demofile-bak
  2. 100.00%
  3. real 2m6.804s
  4. user 0m1.769s
  5. sys 0m22.517s
  6. [root@centos61 ~]# ls -al Demofile*
  7. -rw-r--r--. 1 root root 10485760000 May 27 17:41 Demofile
  8. -rw-r--r--. 1 root root 10485760000 May 27 18:36 Demofile-bak

 

 

三,

脚本说明:

  • $1 代表源文件,本例是Demofile,$2 代表目标文件,本例是Demofile-bak
  • 实际的拷贝命令是在后台运行,因为前台需要显示的是进度条,因此是$CP "$SOURCE" "$TARGET" &

trap "onCtrlC" INT
function onCtrlC () {
        #捕获CTRL+C,当脚本被ctrl+c的形式终止时同时终止程序的后台进程
        kill -9 ${isalive} ${CPID}
        echo
        echo 'Ctrl+C is captured,拷贝已停止'
        exit 1
}

 

这一块是抓取中断信号,如果不想拷贝了的情况下,ctrl+c停止脚本,这样会使得脚本退出更为优雅。

isalive(){
        out=`ps -p $1 2> /dev/null`
        return $?
}

 

这一块是监听拷贝程序的 pid,当返回值为1的时候,表示拷贝完成,程序停止退出。

一个循环的debug如下:

  1. ++ ps -p 35785
  2. + out=' PID TTY TIME CMD
  3. 35785 pts/1 00:00:15 cp'
  4. + return 0
  5. + sleep 1
  6. ++ /bin/ls -l Demofile
  7. ++ gawk '{print $5}'
  8. + SSIZE=10485760000
  9. + '[' -f Demofile-bak ']'
  10. ++ /bin/ls -l Demofile-bak
  11. ++ gawk '{print $5}'
  12. + TSIZE=10337685504
  13. ++ echo 'scale=2; 10337685504/10485760000*100'
  14. ++ bc -l
  15. + PERCENT=98.00
  16. ++ echo 'scale=0; 63*98.00/100'
  17. ++ bc -l
  18. + RATE=61
  19. + BLUE='\033[3;44m'
  20. + NORMAIL='\033[0;39m'
  21. + BAR='\033[3;44m'
  22. + i=0
  23. + '[' 0 -le 62 ']'
  24. + '[' 0 = 61 ']'
  25. + BAR='\033[3;44m '
  26. + let i=0+1
  27. + '[' 1 -le 62 ']'
  28. + '[' 1 = 61 ']'
  29. + BAR='\033[3;44m '
  30. + let i=1+1
  31. + '[' 2 -le 62 ']'
  32. + '[' 2 = 61 ']'
  33. + BAR='\033[3;44m '
  34. + let i=2+1
  35. + '[' 3 -le 62 ']'
  36. + '[' 3 = 61 ']'
  37. + BAR='\033[3;44m '
  38. + let i=3+1
  39. + '[' 4 -le 62 ']'
  40. + '[' 4 = 61 ']'
  41. + BAR='\033[3;44m '
  42. + let i=4+1
  43. + '[' 5 -le 62 ']'
  44. + '[' 5 = 61 ']'
  45. + BAR='\033[3;44m '
  46. + let i=5+1
  47. + '[' 6 -le 62 ']'
  48. + '[' 6 = 61 ']'
  49. + BAR='\033[3;44m '
  50. + let i=6+1
  51. + '[' 7 -le 62 ']'
  52. + '[' 7 = 61 ']'
  53. + BAR='\033[3;44m '
  54. + let i=7+1
  55. + '[' 8 -le 62 ']'
  56. + '[' 8 = 61 ']'
  57. + BAR='\033[3;44m '
  58. + let i=8+1
  59. + '[' 9 -le 62 ']'
  60. + '[' 9 = 61 ']'
  61. + BAR='\033[3;44m '
  62. + let i=9+1
  63. + '[' 10 -le 62 ']'
  64. + '[' 10 = 61 ']'
  65. + BAR='\033[3;44m '
  66. + let i=10+1
  67. + '[' 11 -le 62 ']'
  68. + '[' 11 = 61 ']'
  69. + BAR='\033[3;44m '
  70. + let i=11+1
  71. + '[' 12 -le 62 ']'
  72. + '[' 12 = 61 ']'
  73. + BAR='\033[3;44m '
  74. + let i=12+1
  75. + '[' 13 -le 62 ']'
  76. + '[' 13 = 61 ']'
  77. + BAR='\033[3;44m '
  78. + let i=13+1
  79. + '[' 14 -le 62 ']'
  80. + '[' 14 = 61 ']'
  81. + BAR='\033[3;44m '
  82. + let i=14+1
  83. + '[' 15 -le 62 ']'
  84. + '[' 15 = 61 ']'
  85. + BAR='\033[3;44m '
  86. + let i=15+1
  87. + '[' 16 -le 62 ']'
  88. + '[' 16 = 61 ']'
  89. + BAR='\033[3;44m '
  90. + let i=16+1
  91. + '[' 17 -le 62 ']'
  92. + '[' 17 = 61 ']'
  93. + BAR='\033[3;44m '
  94. + let i=17+1
  95. + '[' 18 -le 62 ']'
  96. + '[' 18 = 61 ']'
  97. + BAR='\033[3;44m '
  98. + let i=18+1
  99. + '[' 19 -le 62 ']'
  100. + '[' 19 = 61 ']'
  101. + BAR='\033[3;44m '
  102. + let i=19+1
  103. + '[' 20 -le 62 ']'
  104. + '[' 20 = 61 ']'
  105. + BAR='\033[3;44m '
  106. + let i=20+1
  107. + '[' 21 -le 62 ']'
  108. + '[' 21 = 61 ']'
  109. + BAR='\033[3;44m '
  110. + let i=21+1
  111. + '[' 22 -le 62 ']'
  112. + '[' 22 = 61 ']'
  113. + BAR='\033[3;44m '
  114. + let i=22+1
  115. + '[' 23 -le 62 ']'
  116. + '[' 23 = 61 ']'
  117. + BAR='\033[3;44m '
  118. + let i=23+1
  119. + '[' 24 -le 62 ']'
  120. + '[' 24 = 61 ']'
  121. + BAR='\033[3;44m '
  122. + let i=24+1
  123. + '[' 25 -le 62 ']'
  124. + '[' 25 = 61 ']'
  125. + BAR='\033[3;44m '
  126. + let i=25+1
  127. + '[' 26 -le 62 ']'
  128. + '[' 26 = 61 ']'
  129. + BAR='\033[3;44m '
  130. + let i=26+1
  131. + '[' 27 -le 62 ']'
  132. + '[' 27 = 61 ']'
  133. + BAR='\033[3;44m '
  134. + let i=27+1
  135. + '[' 28 -le 62 ']'
  136. + '[' 28 = 61 ']'
  137. + BAR='\033[3;44m '
  138. + let i=28+1
  139. + '[' 29 -le 62 ']'
  140. + '[' 29 = 61 ']'
  141. + BAR='\033[3;44m '
  142. + let i=29+1
  143. + '[' 30 -le 62 ']'
  144. + '[' 30 = 61 ']'
  145. + BAR='\033[3;44m '
  146. + let i=30+1
  147. + '[' 31 -le 62 ']'
  148. + '[' 31 = 61 ']'
  149. + BAR='\033[3;44m '
  150. + let i=31+1
  151. + '[' 32 -le 62 ']'
  152. + '[' 32 = 61 ']'
  153. + BAR='\033[3;44m '
  154. + let i=32+1
  155. + '[' 33 -le 62 ']'
  156. + '[' 33 = 61 ']'
  157. + BAR='\033[3;44m '
  158. + let i=33+1
  159. + '[' 34 -le 62 ']'
  160. + '[' 34 = 61 ']'
  161. + BAR='\033[3;44m '
  162. + let i=34+1
  163. + '[' 35 -le 62 ']'
  164. + '[' 35 = 61 ']'
  165. + BAR='\033[3;44m '
  166. + let i=35+1
  167. + '[' 36 -le 62 ']'
  168. + '[' 36 = 61 ']'
  169. + BAR='\033[3;44m '
  170. + let i=36+1
  171. + '[' 37 -le 62 ']'
  172. + '[' 37 = 61 ']'
  173. + BAR='\033[3;44m '
  174. + let i=37+1
  175. + '[' 38 -le 62 ']'
  176. + '[' 38 = 61 ']'
  177. + BAR='\033[3;44m '
  178. + let i=38+1
  179. + '[' 39 -le 62 ']'
  180. + '[' 39 = 61 ']'
  181. + BAR='\033[3;44m '
  182. + let i=39+1
  183. + '[' 40 -le 62 ']'
  184. + '[' 40 = 61 ']'
  185. + BAR='\033[3;44m '
  186. + let i=40+1
  187. + '[' 41 -le 62 ']'
  188. + '[' 41 = 61 ']'
  189. + BAR='\033[3;44m '
  190. + let i=41+1
  191. + '[' 42 -le 62 ']'
  192. + '[' 42 = 61 ']'
  193. + BAR='\033[3;44m '
  194. + let i=42+1
  195. + '[' 43 -le 62 ']'
  196. + '[' 43 = 61 ']'
  197. + BAR='\033[3;44m '
  198. + let i=43+1
  199. + '[' 44 -le 62 ']'
  200. + '[' 44 = 61 ']'
  201. + BAR='\033[3;44m '
  202. + let i=44+1
  203. + '[' 45 -le 62 ']'
  204. + '[' 45 = 61 ']'
  205. + BAR='\033[3;44m '
  206. + let i=45+1
  207. + '[' 46 -le 62 ']'
  208. + '[' 46 = 61 ']'
  209. + BAR='\033[3;44m '
  210. + let i=46+1
  211. + '[' 47 -le 62 ']'
  212. + '[' 47 = 61 ']'
  213. + BAR='\033[3;44m '
  214. + let i=47+1
  215. + '[' 48 -le 62 ']'
  216. + '[' 48 = 61 ']'
  217. + BAR='\033[3;44m '
  218. + let i=48+1
  219. + '[' 49 -le 62 ']'
  220. + '[' 49 = 61 ']'
  221. + BAR='\033[3;44m '
  222. + let i=49+1
  223. + '[' 50 -le 62 ']'
  224. + '[' 50 = 61 ']'
  225. + BAR='\033[3;44m '
  226. + let i=50+1
  227. + '[' 51 -le 62 ']'
  228. + '[' 51 = 61 ']'
  229. + BAR='\033[3;44m '
  230. + let i=51+1
  231. + '[' 52 -le 62 ']'
  232. + '[' 52 = 61 ']'
  233. + BAR='\033[3;44m '
  234. + let i=52+1
  235. + '[' 53 -le 62 ']'
  236. + '[' 53 = 61 ']'
  237. + BAR='\033[3;44m '
  238. + let i=53+1
  239. + '[' 54 -le 62 ']'
  240. + '[' 54 = 61 ']'
  241. + BAR='\033[3;44m '
  242. + let i=54+1
  243. + '[' 55 -le 62 ']'
  244. + '[' 55 = 61 ']'
  245. + BAR='\033[3;44m '
  246. + let i=55+1
  247. + '[' 56 -le 62 ']'
  248. + '[' 56 = 61 ']'
  249. + BAR='\033[3;44m '
  250. + let i=56+1
  251. + '[' 57 -le 62 ']'
  252. + '[' 57 = 61 ']'
  253. + BAR='\033[3;44m '
  254. + let i=57+1
  255. + '[' 58 -le 62 ']'
  256. + '[' 58 = 61 ']'
  257. + BAR='\033[3;44m '
  258. + let i=58+1
  259. + '[' 59 -le 62 ']'
  260. + '[' 59 = 61 ']'
  261. + BAR='\033[3;44m '
  262. + let i=59+1
  263. + '[' 60 -le 62 ']'
  264. + '[' 60 = 61 ']'
  265. + BAR='\033[3;44m '
  266. + let i=60+1
  267. + '[' 61 -le 62 ']'
  268. + '[' 61 = 61 ']'
  269. + BAR='\033[3;44m \033[7;39m'
  270. + BAR='\033[3;44m \033[7;39m '
  271. + let i=61+1
  272. + '[' 62 -le 62 ']'
  273. + '[' 62 = 61 ']'
  274. + BAR='\033[3;44m \033[7;39m '
  275. + let i=62+1
  276. + '[' 63 -le 62 ']'
  277. + BAR='\033[3;44m \033[7;39m \033[0;39m'
  278. + echo -en '\r\033[3;44m \033[7;39m \033[0;39m 98.00%'
  279. 98.00%+ isalive 35785

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/334908
推荐阅读
相关标签
  

闽ICP备14008679号