问题的产生是这样的,当存在大文件的时候,我们需要传输的过程就比较繁复,需要我们思考,如何传输大文件。
我们接下来的思路是:
1、计算这个大文件的md5值,于是之后传输完成的文件的md5对比,确定传输文件的正确性。
文件名是dhsjjg.pdf,这样一个文件,文件大小是44M
md5sum dhsjjg.pdf
我们得到的结果是:
MD5 (dhsjjg.pdf) = 6cf395f9de9d21c2fb02d6380ad1bb0b
2、按照固定的大小分割文件,我们按照4M的大小来分隔文件
split -b 4m dhsjjg.pdf dhsjjg
split 时分隔文件的命令, -b是按照文件的大小分割,-b后面的参数是分割的大小,接下来的参数dhsjjg.pdf是要被分割的文件名,最后的dhsjjg,是分割成功后文件名的前缀。
分割之后的文件的名称是:
dhsjjgaa dhsjjgac dhsjjgae dhsjjgag dhsjjgai dhsjjgak
dhsjjgab dhsjjgad dhsjjgaf dhsjjgah dhsjjgaj
3、计算每个小文件的md5
直接计算:
md5sum dhsjjga*
循环计算:
for var in $(ll |grep dhsjjga | awk '{print $9}'); do md5 $var;done
计算出的每一个文件的md5是:
MD5 (dhsjjgaa) = 57cc415e5f262efa80350683991ab98f
MD5 (dhsjjgab) = 529934d35d2e995be22570ab0b7b4be5
MD5 (dhsjjgac) = 05e73bc8a8918ff087e5bea5820794a0
MD5 (dhsjjgad) = 482b14676a79791e4072b68576d609f8
MD5 (dhsjjgae) = 0b7579cc4e1424a94b5baa515cefb72f
MD5 (dhsjjgaf) = c573b8d84105333fbf462be4cfdd00dd
MD5 (dhsjjgag) = 28e40b436a05ddf0b7390ce17f92f1c1
MD5 (dhsjjgah) = 16d5871447aebefb7e946cc9237c0023
MD5 (dhsjjgai) = 6c35696a09894e43655fc8d0ceb93d69
MD5 (dhsjjgaj) = c60e60c04a7bd92c89359ff19a0a5375
MD5 (dhsjjgak) = 78812952dcb0c9f147eec290a55ed3c9
4、scp 传输所有的小文件
scp dhsjjga* root@127.0.0.1:/data/yll/
文件名 用户名 IP地址 文件目录
5、检查每一个文件的md5值是否和才开始的一样
md5sum dhsjjga*
生成的结果:
57cc415e5f262efa80350683991ab98f dhsjjgaa
529934d35d2e995be22570ab0b7b4be5 dhsjjgab
05e73bc8a8918ff087e5bea5820794a0 dhsjjgac
482b14676a79791e4072b68576d609f8 dhsjjgad
0b7579cc4e1424a94b5baa515cefb72f dhsjjgae
c573b8d84105333fbf462be4cfdd00dd dhsjjgaf
28e40b436a05ddf0b7390ce17f92f1c1 dhsjjgag
16d5871447aebefb7e946cc9237c0023 dhsjjgah
6c35696a09894e43655fc8d0ceb93d69 dhsjjgai
c60e60c04a7bd92c89359ff19a0a5375 dhsjjgaj
78812952dcb0c9f147eec290a55ed3c9 dhsjjgak
对比是否相同,不相同重新传相应的小文件。
6、将小文件合成成大文件,分割时是按照字母顺序来的,合并时也是按照字母顺序来的
cat dhsjjga* > dhsjjg.pdf
7、查看合并成的大文件的md5值
# md5sum dhsjjg.pdf
6cf395f9de9d21c2fb02d6380ad1bb0b dhsjjg.pdf
发现生成的md5的值和之前的一样,说明文件顺利传输。
问题
scp是单线程任务,当有太多的文件的时候,我们需要多线程传输。
接下来我们:
正常情况
# !/bin/bash
for ((i = 0 ;i < 5 ;i ++ )); do
{
sleep 3 ;echo 1 >> aa && echo " done! "
}
done
wait
cat aa | wc - l
rm aa
此时,我们执行下来的时间是:15s,每一条语句3s。
我们接下来修改一下:
# !/bin/bash
for ((i = 0 ;i < 5 ;i ++ )); do
{
sleep 3 ;echo 1 >> aa && echo " done! "
} &
done
wait
cat aa | wc - l
rm aa
我们只是在循环后面加了一个&后台执行符号,此时后台并发执行这5个进程,最后时间是3s。
还需要注意:
wait是等待前面的后台任务全部完成才往下执行,否则程序本身是不会等待的,这样对后面依赖前面任务结果的命令 来说就可能出错。