# 拷贝文件
- 在本机上拷贝文件时:
- 通常使用 cp 命令。
- 跨磁盘拷贝文件时,两个磁盘分别承受读、写负载。在同一磁盘拷贝文件时,读、写负载同时作用于该磁盘,拷贝速度慢很多,不如创建硬链接。
- 跨主机拷贝文件时:
- 通常使用 scp、rsync 命令。
- 跨主机拷贝文件时,磁盘 IO 速度可能比网络 IO 速度快多倍,比如 100MB/s 对 10MB/s 。建议先制作文件的压缩包,拷贝到目标主机之后再解压,使得总耗时更少,只是压缩、解压需要占用一些时间和 CPU 。
- 拷贝大量小文件时,也建议制作压缩包。因为每个文件都需要拷贝一次文件元数据,增加了耗时。
# cp
$ cp <src_path> <dst_path> # 将文件从源路径拷贝到目标路径
-a # 相当于-dpr
-d # 若源文件为 link file ,则复制 link file 的属性(而非文件本身)
-p # 将源文件的权限、属性也拷贝过去(否则会使用默认属性)
-r # 递归操作(用于复制目录)
-f # 若目标文件已存在,则删除它再尝试拷贝
-i # 若目标文件已存在,则提示用户是否进行覆盖
-n # 若目标文件已存在,则不覆盖
-u # --update ,当目标文件不存在,或源文件比目标文件更新时,才执行拷贝
-v # 显示执行过程的详细信息
- Linux 发行版一般设置了
alias cp='cp -i'
,所以 -f 选项无效。 - 例:
cp f1 f2 cp f1 f2 /tmp cp -r * /tmp # 源路径中包含通配符 * 时,不会拷贝隐藏文件 cp -r . /tmp cp -a * /tmp
- 执行
cp f1 f2
时:- 如果 f2 不存在,则会先创建一个空的 f2 文件,再将 f1 的内容拷贝过去。
- 如果 f2 已存在,则会先将 f2 的内容清空,再将 f1 的内容拷贝过去,因此目标文件依然使用 f2 的 inode 号。
- 如果该过程中有其它进程也在修改 f2 ,则会导致 cp 出错。
# ln
:用于创建文件的链接,并不会实际拷贝文件。
- 命令:
$ ln <src_path> <dst_path> # 创建文件的硬链接 -s # 创建文件的软链接 -f # 若目标文件已存在,则覆盖它
- 创建链接时,源路径、目标路径都必须是绝对路径。
- 不支持给目录创建硬链接,不支持跨磁盘分区创建硬链接。
- 可以给目录创建软链接,可以跨磁盘分区创建软链接。
- 例:
[[email protected] ~]# ln -s /tmp tmp [[email protected] ~]# ls -lh total 0 lrwxrwxrwx 1 root root 4 Jan 8 14:21 tmp -> /tmp [[email protected] ~]# rm -f tmp/ # 如果软链接文件指向一个目录,删除时不能加上 / 后缀,否则会被视作删除目标目录 rm: cannot remove ‘tmp/’: Is a directory [[email protected] ~]# rm -f tmp
# dd
:用于在本机上拷贝文件,还支持转换文件格式。不支持拷贝目录。
- 命令:
$ dd if=<file> # 源文件,默认为 stdin of=<file> # 目标文件,默认为 stdout count=<blocks> # 拷贝多少个块(默认为拷贝全部数据) bs=<bytes> # 读写数据时,内存缓冲区的大小。默认为 512 。取值过小会减慢速度,取值过大会占用大量内存 ibs=<bytes> # 每次读取多少字节的数据,默认为 512 obs=<bytes> # 每次写入多少字节的数据,默认为 512
- dd 拷贝文件时,会以 ibs 为单位读取数据,放入内存缓冲区 bs ,然后以 obs 为单位写入目标文件。
- 例:
dd if=/dev/sda1 of=/dev/sda2 # 从 if 设备拷贝数据到 of 设备 dd if=/dev/cdrom of=cd.iso # 拷贝文件并转换成 iso 文件
- 例:
[[email protected] ~]# dd if=/dev/urandom of=f1 bs=1M count=1024 # 拷贝生成一个指定大小、随机内容的文件 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 74.6221 s, 14.4 MB/s [[email protected] ~]# dd if=f1 of=f2 bs=1M # 拷贝文件,这也能测试磁盘的顺序读写速度 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 7.92427 s, 136 MB/s
# scp
:安全拷贝协议(Secure copy protocol),用于在主机之间拷贝文件,基于 SSH 协议加密通信。
- 命令:
$ scp <file>... [email protected]:/root # 将本机的文件拷贝到其它主机(需要通过 SSH 认证) [email protected]:/root/f1 /root # 将其它主机的文件拷贝到本机的指定目录 -C # 传输数据流时启用压缩 -P 22 # 指定 SSH 的端口 -r # 递归操作(用于拷贝目录)
# rsync
:用于在本机拷贝文件、目录,或跨主机拷贝。
- 与 scp 相比:
- rsync 服务默认采用 TCP 873 端口,且不是加密传输。不过可改为基于 SSH 协议传输。
- rsync 将每个文件分成多个文件块传输,如果目标文件中已包含 md5 值相同的块,则不拷贝。因此支持断点续传、增量备份。
- rsync 跨主机拷贝时,需要源主机、目标主机都安装了 rsync 。
- 命令:
$ rsync SRC... DEST # 在本机拷贝文件(此时相当于 cp 命令) SRC... [USER@]HOST:DEST # 将本机的文件拷贝到其它主机 [USER@]HOST:SRC... DEST # 将其它主机的文件拷贝到本机 -e "ssh -p 22" # 基于 SSH 协议加密传输 -z # 传输数据流时启用压缩(不管是本机拷贝,还是跨主机拷贝) -a # 保留文件属性,且递归处理目录 -P # 保留未完全拷贝的文件,并显示传输进度 --ignore-existing # 如果目标文件已存在,则不拷贝 -u # --update ,如果目标文件已存在,且修改时间比源文件更新,则不拷贝 --delete # 删除目标目录比源目录多出的文件 --inplace --append
- 当 SRC 是目录时,如果以 / 结尾,则相当于
cp SRC/* DEST
,否则相当于cp SRC DEST/SRC
。 - 如果 DEST 目录不存在,则会自动创建。
- 当 SRC 是目录时,如果以 / 结尾,则相当于
- 例:
rsync -aP /tmp /data rsync -aP --inplace -e ssh /root/f1 10.0.0.1:/root
- rsync 将 src_file 拷贝文件到 dst_file 时:
- 如果 dst_file 不存在(即目标文件路径未被占用),则从头拷贝 src_file 。
- 拷贝时,默认先暂存到 DEST 目录下一个临时文件。比如拷贝 f1 文件时会暂存为 .f1.GRds8g 文件,等拷贝完才将它重命名为 f1 。如果拷贝中断,则删除该文件。
- 启用 -P 选项时,即使未完全拷贝文件,rsync 就中断,也会将临时文件重命名为 dst_file 。此时该文件是不完整的, modify time 为 1970-01-01 。
- 如果 dst_file 已存在,则检查其 md5 值、文件属性是否与 src_file 一致。
- 如果相同,则不拷贝该文件。
- 如果不同,则默认会从头拷贝 src_file 。
- 例如事先用 cp 命令等其它方式拷贝该文件,即使已经拷贝完,也会因为文件的 modify time 与 src_file 不一致,导致 rsync 从头拷贝该文件。
- 以下情况不会创建临时文件,而是直接保存到 dst_file 。
- 启用 --inplace 选项时,会检查 dst_file 中各个文件块的 md5 值,如果与 src_file 不同,则拷贝。如果文件属性不同,则单独拷贝。
- 启用 --append 选项时,会检查 dst_file 的长度,如果比 src_file 短,则拷贝缺少的字节到 dst_file 的末尾。因此不保证 dst_file 与 src_file 的长度、内容、文件属性一致。
- 综上,如果想实现断点续传,避免从头拷贝文件,建议启用 -P 和 --inplace 选项。
- 如果 dst_file 不存在(即目标文件路径未被占用),则从头拷贝 src_file 。
# dump
dump、restore 命令用于备份本机的文件或目录,适用于 etx2、etx3、etx4 文件系统。
已淘汰不用
$ dump [option] <path> # 备份指定的文件或目录
-f <file> # 保存为指定文件
-[0-9] # 设置备份级别
-j # 压缩为 bzip2 格式
- 备份级别有 0~9 十种,0 是完全备份,1~9 都是增量备份。
- 在备份整个分区或磁盘时才能使用增量备份。比如用 0 完全备份一次之后,可用 1 增量备份。下一次备份时,用 2 就是增量备份(级别加一),用 1 就是差异备份(覆盖之前的同级数据)。
- dump 生成的备份文件并不是普通的压缩文件,还包含了一些备份信息,不能直接解压,只能被 restore 命令使用。
- 例:
dump -j -0f root.back.bz2 /root/
$ restore
-f <file> # 指定备份文件(会根据其中的备份信息,还原到原路径)
-r # 用备份文件进行还原
-t # 显示备份文件的内容
-C # 比较当前文件与备份文件的差异(比如旧文件被修改、删除,但是增加新文件时不算差异)
- restore 会生成一个 restoresymtable 文件,便于在增量备份时传递信息,可以删除。
- 例:
restore -tf root.back.bz2