每天一个linux命令:拷贝命令家族(cp、scp、rsync) — cp
1. cp功能
cp 命令用来将一个或多个源文件或者目录复制到目标文件或目录。
更多精彩请查看:www.zicreate.com
2.命令格式
cp [选项]… [-T] 源 目的
或:cp [选项]… 源… 目录
或:cp [选项]… -t 目录 源…
3.主要命令参数
-a:此参数的效果和同时指定”-dpR”参数相同;
-d:当复制符号连接时,把目标文件或目录也建立为符号连接,并指向与源文件或目录连接的原始文件或目录;
-f:强行复制文件或目录,不论目标文件或目录是否已存在;
-i:覆盖既有文件之前先询问用户;
-l:对源文件建立硬连接,而非复制文件;
-p:保留源文件或目录的属性;
-R/r:递归处理,将指定目录下的所有文件与子目录一并处理;
-s:对源文件建立符号连接,而非复制文件;
-u:使用这项参数后只会在源文件的更改时间较目标文件更新时或是名称相互对应的目标文件并不存在时,才复制文件;
-S:在备份文件时,用指定的后缀“SUFFIX”代替文件的默认后缀;
-b:覆盖已存在的文件目标前将目标文件备份;
-v:详细显示命令执行的操作。
4.使用场景
场景1:文件备份
命令:
备份文件到文件:
$ cp zicreate.txt bak_zicreate.txt
注意:如果不加“-i”参数拷贝,不论bak_zicreate.txt是否存在,命令执行时都不会提示,这种情况下,如果我们拷贝过程中不想覆盖已经存在的同名文件,可以添加“-i”参数。大部分系统中已经对cp命令进行过处理,拷贝时会提示是否覆盖,如下:
$ cp joke.txt bak_joke.txt
cp: overwrite ‘bak_joke.txt’? y
$ which cp
alias cp='cp -i'
/usr/bin/cp
如果觉得每次输入y太繁琐,可以直接取消别名:
$ unaslias cp (这只是临时取消cp的别名)
或者用如下方法同样是取消别名:
$ \cp joke.txt bak_joke.txt
再或者输入:
$ yes | cp joke.txt bak_joke.txt,使用管道自动输入yes。
或备份到指定目录下:
$ cp zicreate.txt ./bak-dir/
或将整个目录备份到指定目录下:
$ cp -r dir1 dir3
注意:如果dir3目录不存在,则会创建目录dir3,如果dir3目录存在,则会将文件夹dir1拷贝到目录dir3里面。
$ cp -r dir1 dir3
$ ls
dir1 dir2 dir3 joke.txt onlyOne.txt test.txt zicreate.txt
$ ls dir3/
test1.txt
$ cp -r dir1 dir3
$ ls dir3/
dir1 test1.txt
场景2:拷贝时保存源文件的所有权限
这种情况主要应用与拷贝程序可执行程序安装包、文件系统目录等特殊场景。
命令:
$cp -rp rootfs/ /mnt/sdcard/
-p参数,可以保持权限、宿主、时间栈,还可能包括link等;还有更简单的,就是用:
$cp -a rootfs/ /mnt/sdcard/
-a参数,就等于-dpR。
前文的文件夹拷贝都是将文件夹整个拷贝到另一个文件夹内,如果是将文件夹内的全部或部分文件拷贝到已经存在的目标文件夹内,则一般使用通配符,如“*”进行目录内容拷贝。
$ ls -a ./dir1
. .. .canotsee.txt test1.txt
$ rm dir3/* -rf
$ ls dir3/ -a
. ..
$ cp dir1/* dir3/ -rf
$ ls dir3/ -a
. .. test1.txt
发现没?使用通配符 “*” 拷贝时,隐藏文件“.canotsee.txt ” 没有被拷贝到目标文件夹内!
原因是:“*” 通配符定义问题,解决方法很简单,用“.” 代替“*”就好了(在Linux中,“.” 代表当前目录,“..” 代表上级目录)。
最终的完全拷贝命令如下:
$ cp dir1/. dir3/ -rf
关于Shell 通配符的解释将会推出后续文章,此处只需要记住, ”*” 代表任意字符串,但是位于首字母位置的“.”除外!