cp复制操作是Linux的基本操作, 其功能是实现对文件或目录的复制, 主要用于对文件的备份和归档等.
根据cp复制操作中根据源文件不同情况, 可能会有不同结果, 这篇文章在这里做下简要分析.
cp的格式为:
cp [OPTION]... SOURCE... DIRECTORY
cp的功能描述为: Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. 复制源文件到目标文件, 或多个文件文件到目标目录.
# 当对多个源文件执行复制操作时, 系统默认最后一个参数为目标目录, 在目标目录之前的参数全部为源文件
根据源文件的不同, 对复制操作进行分析
1) 若SRC是文件格式时, a{1,2}是SRC文件, a.fadir是a{1,2}的父目录, 文件a1和a2中的内容即为其文件名
2) 若SRC是目录格式时, a{1,2}.dir是SRC目录, a1dir.file是a1.dir目录下的文件, a2dir.file时a2.dir目录下的文件, a.fadir是a{1,2}dir的父目录, 文件a1dir.file和a2.dir.file的内容即为其文件名
# b是文件类型的DEST文件, b.dir是目录类型的DEST目录, b.fadir是b的父目录
将当前目录切换到/tmp/中, 在/tmp/目录中新建上述的文件和目录, 目录结构如下所示
tree /tmp/
/tmp/
├── a.fadir
│ ├── a1 #源文件
│ ├── a2 #源文件
│ ├── a1.dir #源目录
│ │ └── a1dir.file
│ └── a2.dir #源目录
│ └── a2dir.file
│
└── b.fadir
├── b #目标文件
└── b.dir #目标目录
1. 当SOURCE是单个文件时, 此时源文件为a1
1-1. DEST是文件, 此时目标文件为b
1-1-1. b不存在但b的父目录b.fadir存在
# rm b.fadir/b #删除目标文件
# cp a.fadir/a1 b.fadir/b #操作实质: 复制源文件 a.fadir/a1 到 b.fadir 中并重命名为b
1-1-2. b的父目录不存在
# rm -rf b.fadir/ #删除目录 b.fadir
# cp a.fadir/a1 b.fadir/b
cp: cannot create regular file `b.fadir/b': No such file or directory #由于路径不存在产生报错
1-1-3. b存在
# mkdir b.fadir #按需创建目录
# touch b.fadir/b #按需创建文件
# cp a.fadir/a1 b.fadir/b
cp: overwrite `b.fadir/b'? #因为系统中的cp实际操作时执行命令别名'cp -i', 因此复制操作后会提示用户是否覆盖目标文件
1-2. DEST是目录, 此时目标文件为b.dir
1-2-1. b.dir不存在(因为刚才rm -rf b.fadir时已经默认将b.dir删除, 此时就不需要再次删除b.dir)
# cp a.fadir/a1 b.fadir/b.dir/
cp: accessing `b.fadir/b.dir/': Not a directory #由于路径不存在会产生报错
1-2-2. b.dir存在
# cp a.fadir/a1 b.fadir/b.dir/ #操作实质: 直接复制文件a1到目标目录b.dir中
2. SOURCE是多个文件时, 即SOURCE为a1和a2; 此时DEST只能是目录b.dir
2-1. b.dir不存在
# rm -rf b.fadir/b.dir/ #删除b.dir目录
# cp a.fadir/a{1,2} b.fadir/b.dir
cp: target `b.fadir/b.dir' is not a directory #由于路径不存在会产生报错
2-2. b.dir存在
# mkdir b.fadir/b.dir
# cp a.fadir/a{1,2} b.fadir/b.dir #操作实质: 直接将源文件a1和a2复制到目标目录中
3. SOURCE是单个目录, 即SOURCE为a1.dir, 此时DEST只能是目录b.dir, 并且在执行复制操作时需要使用 -r 选项
3-1. b.dir不存在
# rm -rf b.fadir/b.dir/ #删除目录b.dir
# cp -r a.fadir/a1.dir/ b.fadir/b.dir #操作实质: 将源目录a1.dir及其目录下的文件爱你复制到DEST所在父目录b.fadir/中, 并将源文件a1.dir重命名为b.dir
# tree a.fadir/ b.fadir/
a.fadir/
├── a1
├── a1.dir
│ └── a1dir.file
├── a2
└── a2.dir
└── a2dir.file
b.fadir/
├── b
└── b.dir
└── a1dir.file
3-2. b.dir存在
# cp -r a.fadir/a1.dir/ b.fadir/b.dir #操作实质: 将源目录a1.dir及其目录下的文件复制到目标目录中
#tree a.fadir/ b.fadir/
a.fadir/
├── a1
├── a1.dir
│ └── a1dir.file
├── a2
└── a2.dir
└── a2dir.file
b.fadir/
├── b
└── b.dir
├── a1.dir
│ └── a1dir.file
└── a1dir.file
4. SOURCE是多个目录, 即SOURCE为a1.dir和a2.dir, 此时DEST只能是目录b.dir, 并且在执行复制操作时需要使用 -r 选项
4-1. b.dir不存在
# rm -rf b.fadir/b.dir/ #先删除目录b.dir
# cp -r a.fadir/a{1,2}.dir b.fadir/b.dir/
cp: target `b.fadir/b.dir/' is not a directory #由于路径不存在会产生报错
4-2. b.dir存在
# mkdir b.fadir/b.dir #先创建目录b.dir
# cp -r a.fadir/a{1,2}.dir b.fadir/b.dir/ #操作实质: 将源目录a1.dir和b1.dir及其目录中的文件复制到目标目录b.dir中
小结:
1. 当DEST为文件格式, 此时SOURCE只能是单个文件的情况, 只要DEST的父目录存在即可执行将源文件复制为目标文件;
2. 当DEST为目录格式且存在情况下, 无论SOURCE的类型(文件/目录)和数量(单个/多个), 都可执行将源文件复制到目标目录中;
3. 当DEST为目录格式且不存在情况下, 只有当SOURCE是单个目录文件时, 才会执行将源目录复制为目标目录.
本人水平有限, 如有理解不当的地方, 请大家给予指正, 非常感谢!