忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
1234下一页
最近访问板块 发新帖
查看: 18105 | 回复: 38

让cp文件也显示进度条[修正版] [复制链接]

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
发表于 2011-09-04 00:09 |显示全部楼层
本帖最后由 zooyo 于 2011-09-04 11:05 编辑

7楼是修正版,不足的大家多提意见,逐步完善.
  1. #!/bin/bash
  2. trap 'exit_fun' 2     #收到Ctrl+Z信号执行函数

  3. usage(){
  4.         echo "Usage: `basename $0` \"src file\" \"dst file\""
  5.         exit 1
  6. }

  7. exit_fun(){        #开启光标显示并退出
  8.         echo -e "\033[?25h"
  9.         exit 1
  10. }

  11. [ "$#" -ne "2" ] && usage
  12. [ -d "$2" ] && k=${2%%/}/`basename $1` || k=$2   #第2个参数是目录的话,自动把文件名补全,方便后面获取文件大小

  13. fromsize=`ls -s $1|cut -d" " -f1`      #获取源文件大小
  14. cp $1 $k &
  15. start=`date +%s`       #开始拷贝时间
  16. sleep 0.2
  17. echo -ne "\033[?25l"   #关闭光标显示,免得影响效果
  18. while :;do
  19.         tosize=`ls -s $k|cut -d" " -f1`        #获取目标文件大小
  20.         x=`echo "100*$tosize/$fromsize"|bc`    #计算拷贝中的目标文件占源文件比例
  21.         [ $x -eq 99 ] && x=100                 #有时候最后完成拷贝时bc计算出两个文件比例是99,不知道什么原因,强行指定为100
  22.         echo -n "["
  23.         for((i=0;i<x;i=$i+2));do echo -n "=";done    #按进度打印等号
  24.         echo -n ">"
  25.         for((j=i;j<=99;j=$j+2));do echo -n " ";done  #打印剩余的空白
  26.         [ $i -lt 10 ] && i="  "$i
  27.         [ $i -gt 9 -a $i -lt 100 ] && i=" "$i        #为了保持格式长度
  28.         now=`date +%s`
  29.         now=$[$now-$start]                           #获取当前时间差,为了计算平均拷贝速度
  30.         [ $now -eq 0 ] && now=1                      #因为从开始拷贝到现在的时间,还没到1秒,该值很可能为0,会给下面的计算造成错误
  31.         avg=$[$tosize/$now/1024]                     #已拷贝文件的大小,除以已用的时间,得出平均速度 M/s
  32.         [ $avg -lt 10 ] && avg="   "$avg
  33.         [ $avg -gt 9 -a $avg -lt 100 ] && avg="  "$avg
  34.         [ $avg -gt 99 ] && avg=" "$avg               #这也是为了保持格式
  35.         echo -n "]  $i%  ${avg}M/s"
  36.         [ $x -ge 100 ] && break                      #当两个文件拷贝完成后退出循环
  37.         sleep 0.1
  38.         echo -ne "\r"                                #清空当前行,后面会有新的打印,这才给我们的眼睛造成了逐步增长的假想
  39. done
  40. echo -e "\033[?25h"                                  #完成后,打开光标显示,如果中途强行退出,我们的函数也会打开光标显示
复制代码
我知道有很多地方都写得不恰当和冗长,发贴的目的是共享和希望大家指正修改.建议拷贝300M以上的大文件测试效果.

评分

参与人数 1可用积分 +4 收起 理由
waker + 4 原创内容

查看全部评分

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
发表于 2011-09-04 03:41 |显示全部楼层
本帖最后由 yinyuemi 于 2011-09-04 03:42 编辑

回复 1# zooyo


    支持!!

   另外,一点小补充:
   1.
  1. exit_fun(){        #开启光标显示并退出

  2.         echo -e "\033[?25h"
  3.         pid=$(ps -ef|awk '/cp$/{print $2}')  # 获取到cp的PID
  4.         kill -9 "$pid"   # kill之
  5.         exit 1

  6. }

  7. 目的是当用户发现copy有误,终止当前程序时,也可以把后台的cp也终止
复制代码
2. 如果是cygwin用户,可能没有bc,
  1.         #x=`echo "100*$tosize/$fromsize"|bc`    #计算拷贝中的目标文件占源文件比例
  2. x=`echo "$tosize $fromsize"|awk '{print int($1*100/$2)}'`
复制代码

评分

参与人数 1可用积分 +2 收起 理由
waker + 2 感谢分享

查看全部评分

论坛徽章:
10
天蝎座
日期:2013-09-22 22:32:23程序设计版块每日发帖之星
日期:2016-08-07 06:20:00lufei
日期:2016-06-17 17:38:40程序设计版块每日发帖之星
日期:2016-06-12 06:20:002016科比退役纪念章
日期:2016-05-31 15:47:20CU十四周年纪念徽章
日期:2016-05-27 12:24:562015年亚洲杯之阿曼
日期:2015-05-03 21:01:352015年辞旧岁徽章
日期:2015-03-03 16:54:15天蝎座
日期:2013-10-20 21:05:24程序设计版块每日发帖之星
日期:2016-08-11 06:20:00
发表于 2011-09-04 08:53 |显示全部楼层
学习

论坛徽章:
1
巳蛇
日期:2013-10-28 15:55:33
发表于 2011-09-04 09:14 |显示全部楼层
本帖最后由 惟吾无为 于 2011-09-04 09:16 编辑

应该截获下signal3, ctrl-c
其实可以用du -xsk 来获取大小, 这样就可以拷贝目录了.
计算$((100*src_size/dest_size)) 够了, 在实时显示 已复制KB数/总KB数
至于计时, 可以在复制函数内
SECONDS=0 # 千万别local, 否则不能计秒了
然后读取SECONDS变量就是已运行的秒数

论坛徽章:
1
巳蛇
日期:2013-10-28 15:55:33
发表于 2011-09-04 09:22 |显示全部楼层
那个保持格式长度, 可以使用printf "%*s" 来解决

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
发表于 2011-09-04 09:51 |显示全部楼层
回复 2# yinyuemi


   
谢谢老师的补充,昨晚也就是想怎么把它搞出来,没去细化考虑.

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
发表于 2011-09-04 10:58 |显示全部楼层
本帖最后由 zooyo 于 2011-09-04 11:03 编辑
  1. #!/bin/bash
  2. trap 'exit_fun' 2

  3. usage(){
  4.         echo "Usage: `basename $0` \"src file\" \"dst file\""
  5.         exit 1
  6. }

  7. exit_fun(){
  8.         echo -e "\033[?25h"
  9.         kill -9 $(ps -ef|awk '/ [c]p /{print $2}') &>/dev/null
  10.         exit 1
  11. }


  12. [ "$#" -ne "2" ] && usage
  13. [ -d "$2" ] && k=${2%%/}/`basename $1` || k=$2

  14. fromsize=`ls -s $1|cut -d" " -f1`
  15. cp $1 $k &
  16. start=`date +%s`
  17. sleep 0.2
  18. echo -ne "\033[?25l"
  19. while :;do
  20.         tosize=`ls -s $k|cut -d" " -f1`
  21.         x=`echo "$tosize $fromsize"|awk '{print int($1*100/$2)}'`
  22.         [ $x -eq 99 ] && x=100
  23.         echo -n "["
  24.         for((i=0;i<x;i=$i+2));do echo -n "=";done
  25.         echo -n ">"
  26.         for((j=i;j<=99;j=$j+2));do echo -n " ";done
  27.         now=$[`date +%s` - $start]
  28.         [ $now -eq 0 ] && now=1
  29.         avg=$[$tosize/$now/1024]
  30.         printf "]  %4s%%  %4sM/s" $i $avg
  31.         [ $x -ge 100 ] && break
  32.         sleep 0.1
  33.         echo -ne "\r"
  34. done
  35. echo -e "\033[?25h"
复制代码

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:55:28
发表于 2011-09-04 11:34 |显示全部楼层
学习~高手夜里都不带睡觉的吧。。。厉害!

论坛徽章:
0
发表于 2011-09-05 09:11 |显示全部楼层
回复 1# zooyo


    强!顶。

论坛徽章:
0
发表于 2011-09-05 09:20 |显示全部楼层
顶zooyo!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:wangnan@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP