默认行为
cp 命令在不带任何选项的情况下,其核心默认行为可以总结为:

复制文件或目录,如果是目录,则必须加上
-r或-R选项才能递归复制其内容。
下面我们通过具体的例子和 --verbose 选项来验证这一点。
复制文件(默认行为)
当你复制一个文件时,cp 默认会:
- 覆盖目标文件中已存在的同名文件,且不会提示确认。
- 保持文件的权限、所有者和时间戳(如果可能)。
示例: 假设我们有以下文件:

$ ls -l -rw-r--r-- 1 user user 12 Oct 26 10:30 source.txt -rw-r--r-- 1 user user 20 Oct 26 10:31 destination.txt
source.txt 内容是 "Hello",destination.txt 内容是 "World"。
我们执行 cp source.txt destination.txt:
$ cp source.txt destination.txt
因为没有提示,所以操作直接完成,我们查看结果:
$ cat destination.txt Hello # destination.txt 的内容被 source.txt 覆盖了 $ ls -l -rw-r--r-- 1 user user 12 Oct 26 10:32 destination.txt # 文件大小和时间戳被更新
cp 默认会静默覆盖目标文件。

复制目录(默认行为)
当你尝试直接复制一个目录时,cp 默认会报错,因为它不知道如何处理目录内部的内容。
示例:
假设我们有一个目录 my_dir:
$ mkdir my_dir $ echo "inside dir" > my_dir/file.txt $ ls -l drwxr-xr-x 2 user user 40 Oct 26 10:35 my_dir
尝试直接复制目录:
$ cp my_dir new_dir cp: omitting directory 'my_dir' # 报错:忽略目录
cp 命令认为你想要把 my_dir 这个目录本身作为一个文件来复制,但它是一个目录,所以它拒绝了。
正确的做法: 使用 -r (recursive) 或 -R 选项。
$ cp -r my_dir new_dir
new_dir 被成功创建,并且包含了 my_dir 的所有内容。
使用 --help 查看所有默认参数
要查看 cp 命令的完整帮助信息,包括所有默认值,可以使用 --help 选项。
$ cp --help
在输出的信息中,你会看到类似这样的行:
Usage: cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...
这表示 cp 的基本用法是 cp 源文件 目标文件 或 cp 源文件... 目标目录。
重要默认行为的深入解析
覆盖行为(没有 -i 选项)
这是 cp 最需要注意的一个默认行为,它会直接覆盖,不会像 mv 命令在某些配置下那样会提示你 "是否覆盖?"。
示例:
# 创建一个重要文件 $ echo "重要数据" > important_file.txt # 用一个空文件去覆盖它 $ cp /dev/null important_file.txt # 文件被直接清空,没有任何警告 $ cat important_file.txt
安全建议: 在生产环境或不确定的情况下,强烈建议使用 -i (interactive) 选项,它会让你在覆盖前进行确认。
$ cp -i source.txt destination.txt cp: overwrite 'destination.txt'? y # 输入 y 确认,n 取消
保留属性(默认保留)
cp 默认会尽可能地保留源文件的元数据,包括:
- 权限:
-p选项(--preserve=mode)是默认行为的一部分。 - 时间戳:
-p选项(--preserve=timestamps)也是默认行为的一部分。 - 所有者: 这一点不是默认行为,默认情况下,新文件的所有者是执行
cp命令的用户。
示例:
$ sudo touch /root/protected_file # 创建一个 root 拥有的文件 $ ls -l /root/protected_file -rw-r--r-- 1 root root 0 Oct 26 10:40 /root/protected_file $ cp /root/protected_file ./my_copy.txt $ ls -l my_copy.txt -rw-r--r-- 1 your_user your_user 0 Oct 26 10:41 my_copy.txt # 所有者变成了当前用户
如果你想保留所有者,需要使用 -a 选项。
符号链接的处理(默认跟随)
默认情况下,cp 会跟随符号链接,它复制的是符号链接指向的实际文件内容,而不是链接本身。
示例:
$ echo "original content" > original.txt $ ln -s original.txt my_link.txt $ cp my_link.txt copied_link.txt $ ls -l lrwxrwxrwx 1 user user 12 Oct 26 10:45 my_link.txt -> original.txt -rw-r--r-- 1 user user 17 Oct 26 10:46 copied_link.txt # 这是一个普通文件,不是链接 $ cat copied_link.txt original content
如果你想复制符号链接本身(不跟随),需要使用 -P 或 --no-dereference 选项。
常用选项及其与默认行为的对比
| 选项 | 全称 | 描述 | 与默认行为的区别 |
|---|---|---|---|
-a |
--archive |
归档模式,相当于 -dpR 的集合,保留所有属性(权限、时间戳、所有者等),并递归复制。 |
最常用的完整复制选项,默认不保留所有者,-a 会保留。 |
-i |
--interactive |
交互式,在覆盖文件前提示用户确认。 | 强烈推荐用于安全操作,默认是静默覆盖。 |
-r |
--recursive |
递归,复制目录及其所有内容。 | 默认情况下不能复制目录内容,必须加此选项。 |
-v |
--verbose |
详细,显示正在复制的文件列表。 | 默认是静默操作,不显示任何过程信息。 |
-p |
--preserve |
保留属性,保留文件的权限、所有者、时间戳等。 | 默认保留权限和时间戳,但不保留所有者。-p 会强制保留所有者(如果权限允许)。 |
-f |
--force |
强制,如果目标文件无法打开,则先将其删除再尝试复制。 | 默认行为在某些情况下会提示,-f 会使其更激进地覆盖。 |
-P |
--no-dereference |
不跟随符号链接,复制链接本身,而不是它指向的文件。 | 默认会跟随符号链接,复制目标文件的内容。 |
总结表格
| 操作场景 | 默认 cp 行为 |
推荐的安全/完整命令 |
|---|---|---|
| 复制文件 | 静默覆盖目标文件,保留权限和时间戳。 | cp -i source.txt destination.txt |
| 复制目录 | 报错,无法复制。 | cp -r source_dir destination_dir 或 cp -a source_dir destination_dir |
| 复制重要文件 | 静默覆盖,风险高。 | cp -i source.txt destination.txt |
| 想要完整备份 | 不保留所有者,只保留基本属性。 | cp -a /path/to/source /path/to/backup |
| 复制符号链接 | 复制链接指向的实际文件内容。 | cp -P source_link.txt dest_link.txt (复制链接本身) |
理解 cp 的这些默认行为对于安全、高效地使用 Linux 命令行至关重要,特别是 -i 选项,应该成为你的肌肉记忆。
