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

简介: Linux|shell编程|拷贝大文件之显示进度条

前言:

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

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

一,

测试文件的准备

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

我的硬盘速度还算可以的

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

二,

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

#!/bin/bash
SOURCE=$1
TARGET=$2
CP=cp
$CP "$SOURCE" "$TARGET" &
CPID=$!
trap "onCtrlC" INT 
function onCtrlC () {
        #捕获CTRL+C,当脚本被ctrl+c的形式终止时同时终止程序的后台进程
        kill -9 ${isalive} ${CPID}
        echo
        echo 'Ctrl+C is captured,拷贝已停止'
        exit 1
}
isalive(){
        out=`ps -p $1 2> /dev/null`
        return $?
}
while 2>1; do
 { SSIZE=`/bin/ls -l $SOURCE | gawk "{print \\\$5}"`
        if [ -f $TARGET ]; then
                TSIZE=`/bin/ls -l $TARGET | gawk "{print \\\$5}"`
        else
                TSIZE="0"
        fi
        PERCENT=`echo "scale=2; $TSIZE/$SSIZE*100" | bc -l`
        RATE=`echo "scale=0; 63*$PERCENT/100" | bc -l`
        BLUE="\\033[3;44m"
        NORMAIL="\\033[0;39m"
        BAR=$BLUE
        i=0
        while [ $i -le 62 ]; do
                [ $i = $RATE ] && BAR=$BAR"\\033[7;39m"
                BAR=$BAR" "
                let i=$i+1
        done
        BAR=$BAR$NORMAIL
        echo -en "\r$BAR ${PERCENT}%"
        if ! isalive "$CPID"; then echo -en "\n"; exit; fi
        sleep 1
}
done

脚本运行效果:

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

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

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

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

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

完整运行:

[root@centos61 ~]# time bash copyfile.sh Demofile Demofile-bak
                                                                100.00%
real  2m6.804s
user  0m1.769s
sys 0m22.517s
[root@centos61 ~]# ls -al Demofile*
-rw-r--r--. 1 root root 10485760000 May 27 17:41 Demofile
-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如下:

++ ps -p 35785
+ out='   PID TTY          TIME CMD
 35785 pts/1    00:00:15 cp'
+ return 0
+ sleep 1
++ /bin/ls -l Demofile
++ gawk '{print $5}'
+ SSIZE=10485760000
+ '[' -f Demofile-bak ']'
++ /bin/ls -l Demofile-bak
++ gawk '{print $5}'
+ TSIZE=10337685504
++ echo 'scale=2; 10337685504/10485760000*100'
++ bc -l
+ PERCENT=98.00
++ echo 'scale=0; 63*98.00/100'
++ bc -l
+ RATE=61
+ BLUE='\033[3;44m'
+ NORMAIL='\033[0;39m'
+ BAR='\033[3;44m'
+ i=0
+ '[' 0 -le 62 ']'
+ '[' 0 = 61 ']'
+ BAR='\033[3;44m '
+ let i=0+1
+ '[' 1 -le 62 ']'
+ '[' 1 = 61 ']'
+ BAR='\033[3;44m  '
+ let i=1+1
+ '[' 2 -le 62 ']'
+ '[' 2 = 61 ']'
+ BAR='\033[3;44m   '
+ let i=2+1
+ '[' 3 -le 62 ']'
+ '[' 3 = 61 ']'
+ BAR='\033[3;44m    '
+ let i=3+1
+ '[' 4 -le 62 ']'
+ '[' 4 = 61 ']'
+ BAR='\033[3;44m     '
+ let i=4+1
+ '[' 5 -le 62 ']'
+ '[' 5 = 61 ']'
+ BAR='\033[3;44m      '
+ let i=5+1
+ '[' 6 -le 62 ']'
+ '[' 6 = 61 ']'
+ BAR='\033[3;44m       '
+ let i=6+1
+ '[' 7 -le 62 ']'
+ '[' 7 = 61 ']'
+ BAR='\033[3;44m        '
+ let i=7+1
+ '[' 8 -le 62 ']'
+ '[' 8 = 61 ']'
+ BAR='\033[3;44m         '
+ let i=8+1
+ '[' 9 -le 62 ']'
+ '[' 9 = 61 ']'
+ BAR='\033[3;44m          '
+ let i=9+1
+ '[' 10 -le 62 ']'
+ '[' 10 = 61 ']'
+ BAR='\033[3;44m           '
+ let i=10+1
+ '[' 11 -le 62 ']'
+ '[' 11 = 61 ']'
+ BAR='\033[3;44m            '
+ let i=11+1
+ '[' 12 -le 62 ']'
+ '[' 12 = 61 ']'
+ BAR='\033[3;44m             '
+ let i=12+1
+ '[' 13 -le 62 ']'
+ '[' 13 = 61 ']'
+ BAR='\033[3;44m              '
+ let i=13+1
+ '[' 14 -le 62 ']'
+ '[' 14 = 61 ']'
+ BAR='\033[3;44m               '
+ let i=14+1
+ '[' 15 -le 62 ']'
+ '[' 15 = 61 ']'
+ BAR='\033[3;44m                '
+ let i=15+1
+ '[' 16 -le 62 ']'
+ '[' 16 = 61 ']'
+ BAR='\033[3;44m                 '
+ let i=16+1
+ '[' 17 -le 62 ']'
+ '[' 17 = 61 ']'
+ BAR='\033[3;44m                  '
+ let i=17+1
+ '[' 18 -le 62 ']'
+ '[' 18 = 61 ']'
+ BAR='\033[3;44m                   '
+ let i=18+1
+ '[' 19 -le 62 ']'
+ '[' 19 = 61 ']'
+ BAR='\033[3;44m                    '
+ let i=19+1
+ '[' 20 -le 62 ']'
+ '[' 20 = 61 ']'
+ BAR='\033[3;44m                     '
+ let i=20+1
+ '[' 21 -le 62 ']'
+ '[' 21 = 61 ']'
+ BAR='\033[3;44m                      '
+ let i=21+1
+ '[' 22 -le 62 ']'
+ '[' 22 = 61 ']'
+ BAR='\033[3;44m                       '
+ let i=22+1
+ '[' 23 -le 62 ']'
+ '[' 23 = 61 ']'
+ BAR='\033[3;44m                        '
+ let i=23+1
+ '[' 24 -le 62 ']'
+ '[' 24 = 61 ']'
+ BAR='\033[3;44m                         '
+ let i=24+1
+ '[' 25 -le 62 ']'
+ '[' 25 = 61 ']'
+ BAR='\033[3;44m                          '
+ let i=25+1
+ '[' 26 -le 62 ']'
+ '[' 26 = 61 ']'
+ BAR='\033[3;44m                           '
+ let i=26+1
+ '[' 27 -le 62 ']'
+ '[' 27 = 61 ']'
+ BAR='\033[3;44m                            '
+ let i=27+1
+ '[' 28 -le 62 ']'
+ '[' 28 = 61 ']'
+ BAR='\033[3;44m                             '
+ let i=28+1
+ '[' 29 -le 62 ']'
+ '[' 29 = 61 ']'
+ BAR='\033[3;44m                              '
+ let i=29+1
+ '[' 30 -le 62 ']'
+ '[' 30 = 61 ']'
+ BAR='\033[3;44m                               '
+ let i=30+1
+ '[' 31 -le 62 ']'
+ '[' 31 = 61 ']'
+ BAR='\033[3;44m                                '
+ let i=31+1
+ '[' 32 -le 62 ']'
+ '[' 32 = 61 ']'
+ BAR='\033[3;44m                                 '
+ let i=32+1
+ '[' 33 -le 62 ']'
+ '[' 33 = 61 ']'
+ BAR='\033[3;44m                                  '
+ let i=33+1
+ '[' 34 -le 62 ']'
+ '[' 34 = 61 ']'
+ BAR='\033[3;44m                                   '
+ let i=34+1
+ '[' 35 -le 62 ']'
+ '[' 35 = 61 ']'
+ BAR='\033[3;44m                                    '
+ let i=35+1
+ '[' 36 -le 62 ']'
+ '[' 36 = 61 ']'
+ BAR='\033[3;44m                                     '
+ let i=36+1
+ '[' 37 -le 62 ']'
+ '[' 37 = 61 ']'
+ BAR='\033[3;44m                                      '
+ let i=37+1
+ '[' 38 -le 62 ']'
+ '[' 38 = 61 ']'
+ BAR='\033[3;44m                                       '
+ let i=38+1
+ '[' 39 -le 62 ']'
+ '[' 39 = 61 ']'
+ BAR='\033[3;44m                                        '
+ let i=39+1
+ '[' 40 -le 62 ']'
+ '[' 40 = 61 ']'
+ BAR='\033[3;44m                                         '
+ let i=40+1
+ '[' 41 -le 62 ']'
+ '[' 41 = 61 ']'
+ BAR='\033[3;44m                                          '
+ let i=41+1
+ '[' 42 -le 62 ']'
+ '[' 42 = 61 ']'
+ BAR='\033[3;44m                                           '
+ let i=42+1
+ '[' 43 -le 62 ']'
+ '[' 43 = 61 ']'
+ BAR='\033[3;44m                                            '
+ let i=43+1
+ '[' 44 -le 62 ']'
+ '[' 44 = 61 ']'
+ BAR='\033[3;44m                                             '
+ let i=44+1
+ '[' 45 -le 62 ']'
+ '[' 45 = 61 ']'
+ BAR='\033[3;44m                                              '
+ let i=45+1
+ '[' 46 -le 62 ']'
+ '[' 46 = 61 ']'
+ BAR='\033[3;44m                                               '
+ let i=46+1
+ '[' 47 -le 62 ']'
+ '[' 47 = 61 ']'
+ BAR='\033[3;44m                                                '
+ let i=47+1
+ '[' 48 -le 62 ']'
+ '[' 48 = 61 ']'
+ BAR='\033[3;44m                                                 '
+ let i=48+1
+ '[' 49 -le 62 ']'
+ '[' 49 = 61 ']'
+ BAR='\033[3;44m                                                  '
+ let i=49+1
+ '[' 50 -le 62 ']'
+ '[' 50 = 61 ']'
+ BAR='\033[3;44m                                                   '
+ let i=50+1
+ '[' 51 -le 62 ']'
+ '[' 51 = 61 ']'
+ BAR='\033[3;44m                                                    '
+ let i=51+1
+ '[' 52 -le 62 ']'
+ '[' 52 = 61 ']'
+ BAR='\033[3;44m                                                     '
+ let i=52+1
+ '[' 53 -le 62 ']'
+ '[' 53 = 61 ']'
+ BAR='\033[3;44m                                                      '
+ let i=53+1
+ '[' 54 -le 62 ']'
+ '[' 54 = 61 ']'
+ BAR='\033[3;44m                                                       '
+ let i=54+1
+ '[' 55 -le 62 ']'
+ '[' 55 = 61 ']'
+ BAR='\033[3;44m                                                        '
+ let i=55+1
+ '[' 56 -le 62 ']'
+ '[' 56 = 61 ']'
+ BAR='\033[3;44m                                                         '
+ let i=56+1
+ '[' 57 -le 62 ']'
+ '[' 57 = 61 ']'
+ BAR='\033[3;44m                                                          '
+ let i=57+1
+ '[' 58 -le 62 ']'
+ '[' 58 = 61 ']'
+ BAR='\033[3;44m                                                           '
+ let i=58+1
+ '[' 59 -le 62 ']'
+ '[' 59 = 61 ']'
+ BAR='\033[3;44m                                                            '
+ let i=59+1
+ '[' 60 -le 62 ']'
+ '[' 60 = 61 ']'
+ BAR='\033[3;44m                                                             '
+ let i=60+1
+ '[' 61 -le 62 ']'
+ '[' 61 = 61 ']'
+ BAR='\033[3;44m                                                             \033[7;39m'
+ BAR='\033[3;44m                                                             \033[7;39m '
+ let i=61+1
+ '[' 62 -le 62 ']'
+ '[' 62 = 61 ']'
+ BAR='\033[3;44m                                                             \033[7;39m  '
+ let i=62+1
+ '[' 63 -le 62 ']'
+ BAR='\033[3;44m                                                             \033[7;39m  \033[0;39m'
+ echo -en '\r\033[3;44m                                                             \033[7;39m  \033[0;39m 98.00%'
                                                                98.00%+ isalive 35785


目录
相关文章
|
5天前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
25 5
|
5天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
17 6
|
5天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
25 5
|
6天前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
20 4
|
12天前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
33 2
|
11天前
|
缓存 监控 Linux
|
14天前
|
Linux Shell 数据库
文件查找是Linux用户日常工作的重要技能介绍了几种不常见的文件查找方法
文件查找是Linux用户日常工作的重要技能。本文介绍了几种不常见的文件查找方法,包括使用`find`和`column`组合、`locate`和`mlocate`快速查找、编写Shell脚本、使用现代工具`fd`、结合`grep`搜索文件内容,以及图形界面工具如`Gnome Search Tool`和`Albert`。这些方法能显著提升文件查找的效率和准确性。
35 2
|
17天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
17天前
|
Linux 数据库
linux 全局搜索文件
在 Linux 系统中,全局搜索文件常用 `find`、`locate` 和 `grep` 命令。`find` 根据文件名、类型、大小、时间戳等条件搜索;`locate` 通过预构建的数据库快速查找文件;`grep` 在文件中搜索特定文本,常与 `find` 结合使用。选择合适的命令取决于具体需求。
Linux 怎么修改最大文件打开数量?
-H选项和-S选项分别表示对给定资源的硬限制(hard limit)和软限制(soft limit)进行设置。 硬限制(hard limit)一旦被设置以后就不能被非root用户修改,软限制(soft limit)可以增长达到硬限制(hard limit)。
Linux 怎么修改最大文件打开数量?