Linux教程网

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 选项进入交互界面,用户可以输入 yn 来选择是否覆盖。

1
2
3
4
# 不覆盖
$ cp -n foo.txt bar.txt
# 进入交互界面,在提示符输入y或n
$ cp -i foo.txt bar.txt

需要注意的是,有些系统为了安全起见,默认会为 cp 命令设置 alias 别名,增加 -i 选项,如果目的文件存在,默认就会进入提示界面。大部分情况下,在脚本中要用户进行交互是很不方便的,可以通过指定 -f 选项,或者使用命令的全路径 /bin/cp 这样的方式进行解决。

4. 拷贝已存在的目录

如果拷贝的是目录,且目标目录已存在,会发生什么呢?我们先来做个简单实验,希望将 foo 目录拷贝为 bar,如果存在完全覆盖

1
2
3
$ cp -rp foo bar
$ ls bar
foo

结果是将 foo 目录拷贝到 bar 目录下,而不是在直接覆盖 bar 目录。通过查找资料和多次实验,发现通过 cp 命令本身无法做到,可以使用如下方式,虽然不优雅但能解决问题

1
$ /bin/rm -r bar && /bin/cp -r foo bar

5. 拷贝多个文件或目录

上边的实验代码拷贝的都是单个目录或文件,其实 cp 可以同时拷贝多个文件和目录

1
2
3
4
$ cp -rp -v a.txt b.txt foo /root/
"a.txt" -> "/root/a.txt"
"b.txt" -> "/root/b.txt"
"foo" -> "/root/foo

上述命令表示将 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
2
3
4
5
6
$ ln -s foo.txt foo.link.txt
$ cp -P foo.link.txt bar.txt
$ ls -l
lrwxrwxrwx 1 root root 7 5月 30 22:36 bar.txt -> foo.txt
lrwxrwxrwx 1 root root 7 5月 30 22:35 foo.link.txt -> foo.txt
-rw-r--r-- 1 root root 0 5月 30 22:35 foo.txt

可以看到 bar.txt 也是软连接文件,指向 foo.txt 文件

8. 拷贝较新的文件

当我们在拷贝大文件时,只希望在文件有更新时再去拷贝和覆盖旧文件,这样可以避免无谓的磁盘拷贝,通过指定 -u 选型即可

1
$ cp -u bignew.txt bigfile.txt

如果 bigfile.txt 文件不存在,则一定会发生拷贝;如果 bigfile.txt 存在且比 bignew.txt 文件新,则不会拷贝。

-u 拷贝大文件时,如果没有变化,就不要拷贝了


专题:

本文发表于 2022-05-30,最后修改于 2023-09-17。

本站永久域名「 golinuxblog.com 」,也可搜索「 Linux教程网 」找到我。


上一篇 « 留言板 下一篇 » Linux文件移动命令mv

推荐阅读

Big Image