Linux文件拷贝命令cp
cp 命令,全称为 copy,可以用来拷贝文件或目录。
语法选项
命令语法很简单,如下所示
1 | cp [OPTION] SOURCE DEST |
SOURCE 指的是源文件,也就是被拷贝的文件或目录,DEST 为目标文件,也就是拷贝后生成的文件或目录。需要注意的是 SOURCE 可以是多个文件或目录。
常用的命令选项,总结如下
-f:如果目的文件存在,强制直接覆盖,长选项--force-i:如果目的文件存在,则进入交互模式,需要在提示符后输入y确认后覆盖-p:拷贝时保持源文件的属性包括:权限模式、属主属组、时间戳-r:递归拷贝源目录中所有的内容-l:拷贝的是硬链接而不是文件的副本,两个文件的inode是一样的-v:显示拷贝详情,在脚本中使用该选项非常有用-a:拷贝生成的文件或目录与源文件属性完全一样-b:如果目的文件存在,则先备份再拷贝-s:拷贝的是软连接而不是文件的副本-u:如果目的文件存在,只有当源文件比目的文件更新时才拷贝-P:如果源文件是软连接,拷贝的是软连接文件本身,而不是软连接指向的文件-n:如果目的文件存在,不要覆盖文件
上边只罗列了 cp 命令中常用的选项,基本可以满足大部分日常工作需求。如上述选项不能够满足需求,可以自己 man cp 查看手册详情。
用法示例
接下来,总结一些 cp 命令常见的使用方法
1. 文件拷贝。如果要拷贝到别的目录,目的文件需要指定目录
1 | $ cp foo.txt bar.txt |
2. 目录拷贝。如果是目录需要指定 -r 选项,可以将整个目录所有的内容都拷贝过去
1 | $ cp -r conf conf.bak |
如果希望拷贝时继承源目录的属性,同时指定 -p 选项即可
3. 拷贝已存在的文件
通过 cp 拷贝文件,如果目的文件已存在,默认会直接覆盖目的文件。如果希望不覆盖,可以指定 -n 选项;指定 -i 选项进入交互界面,用户可以输入 y 或 n 来选择是否覆盖。
1 | # 不覆盖 |
需要注意的是,有些系统为了安全起见,默认会为 cp 命令设置 alias 别名,增加 -i 选项,如果目的文件存在,默认就会进入提示界面。大部分情况下,在脚本中要用户进行交互是很不方便的,可以通过指定 -f 选项,或者使用命令的全路径 /bin/cp 这样的方式进行解决。
4. 拷贝已存在的目录
如果拷贝的是目录,且目标目录已存在,会发生什么呢?我们先来做个简单实验,希望将 foo 目录拷贝为 bar,如果存在完全覆盖
1 | $ cp -rp foo bar |
结果是将 foo 目录拷贝到 bar 目录下,而不是在直接覆盖 bar 目录。通过查找资料和多次实验,发现通过 cp 命令本身无法做到,可以使用如下方式,虽然不优雅但能解决问题
1 | $ /bin/rm -r bar && /bin/cp -r foo bar |
5. 拷贝多个文件或目录
上边的实验代码拷贝的都是单个目录或文件,其实 cp 可以同时拷贝多个文件和目录
1 | $ cp -rp -v a.txt b.txt foo /root/ |
上述命令表示将 a.txt 文件、b.txt 文件、foo 目录拷贝到 /root 目录下。可以看到命令执行时,会显示每个文件拷贝的详情,这是由于添加了 -v 选项,在拷贝多个文件时非常有用。
6. 拷贝硬链接而不是文件副本
1 | $ cp -l foo.txt foo2.txt |
上述命令指定 -l 选项,表示为 foo.txt 文件创建了硬链接文件 foo2.txt,而不是文件副本,相当于为 foo.txt 设置一个别名
7. 拷贝软连接文件
如果源文件时软连接,默认 cp 会拷贝软连接指向的目标文件。如果我们希望只是拷贝软连接文件本身,而不是所指向的文件,可以使用 -P 选项
1 | $ ln -s foo.txt foo.link.txt |
可以看到 bar.txt 也是软连接文件,指向 foo.txt 文件
8. 拷贝较新的文件
当我们在拷贝大文件时,只希望在文件有更新时再去拷贝和覆盖旧文件,这样可以避免无谓的磁盘拷贝,通过指定 -u 选型即可
1 | $ cp -u bignew.txt bigfile.txt |
如果 bigfile.txt 文件不存在,则一定会发生拷贝;如果 bigfile.txt 存在且比 bignew.txt 文件新,则不会拷贝。
-u 拷贝大文件时,如果没有变化,就不要拷贝了



