cp 是什么
cp 把源文件的内容读出来写到目标位置,目标是一个全新的 inode,因此会真实占用两份空间,也不会与源文件共享后续修改。这一点是与 mv 的关键区别:同一文件系统内 mv 只改目录项,瞬间完成且不消耗额外空间。cp 默认会直接覆盖已存在的目标,且 cp -r 复制出的文件权限由 umask 重新生成,只有 -a 归档模式才会把权限、时间戳、属主、链接等元数据一并带过去。
基本信息
| 适用平台 | Linux 全发行版与 macOS(GNU coreutils / BSD cp,部分选项如 -t、--reflink 属 GNU 扩展) |
|---|---|
| 命令语法 | cp [选项] 源... 目标;多个源时目标必须是已存在的目录 |
| 常用选项 | -a 归档(等于 -dR --preserve=all)、-r/-R 递归、-p 保留属性、-i 覆盖前询问、-n 不覆盖、-u 仅复制更新的、-v 显示过程、-t 指定目标目录、-l 建硬链接、-s 建符号链接 |
| 权限要求 | 目标目录需要写权限;要保留属主与属组需要 root,普通用户执行 -a 时属主会变成自己 |
| 补充说明 | -a 隐含 -d,遇到符号链接时复制链接本身而不是它指向的内容 |
典型使用场景
- 改配置前备份:cp -a /etc/nginx /etc/nginx.bak 保留权限与时间戳,回滚时直接换回目录
- 跨文件系统搬运:源与目标不在同一分区时 mv 会退化成复制加删除,用 cp 更可控
- 模板分发:把带占位符的配置模板复制到多个实例目录,再用 sed 替换变量
- 增量发布:cp -u 只覆盖源端更新的文件,适合配置文件的小幅同步
- 本地快速副本:先用 -l 建硬链接省空间,等确认无误再改成实体复制
- 保留目录结构:用 cp --parents 复制时自动创建缺失的上级目录
常用示例
常用示例
cp -a /etc/nginx /etc/nginx.bak # 归档复制整个目录(推荐备份方式)
cp -i report.txt /backup/ # 覆盖前询问
cp -u *.conf /etc/app/conf.d/ # 仅复制更新过的文件
cp -r /data/site/. /backup/site/ # 复制目录内容(含隐藏文件)
cp -a --parents /etc/nginx/nginx.conf /backup/ # 连同目录结构一起复制
cp --reflink=auto big.img /backup/ # 支持的文件系统上做写时复制,省空间选项对照
| 选项 | 保留/作用 | 使用建议 |
|---|---|---|
| -a | 递归 + 权限、属主、时间戳、链接、扩展属性 | 备份与整目录复制一律用它 |
| -r | 仅递归,新文件权限由 umask 决定 | 复制后需要重新设置权限的场景少用 |
| -p | 保留权限、属主、时间戳 | 不带 -r,配 -r 用于目录 |
| -n | 已存在则跳过,不覆盖 | 脚本防误覆盖的首选 |
| -u | 仅当源更新时才复制 | 增量同步的简化版;判断依据是时间戳 |
| -f | 目标无法打开时先删除再复制 | 默认行为在多数环境下与 -f 相同 |
源目录结尾的 /. 是可移植的写法:cp -r /data/site/. /backup/site/ 表示把目录内容(包括隐藏文件)复制进目标目录;漏掉 /. 时若目标目录已存在,实际结果往往也对,但目标不存在时行为会有差异,写脚本时统一带上 /. 更省心。
复制大文件想看进度,cp 本身只有 -v(逐文件输出)。要看到速率与百分比,用 rsync --info=progress2 或 pv 命令配合管道:pv big.img > /backup/big.img。
cp 到已存在的文件是静默覆盖的,误覆盖的后果与删除相当。交互场景加 -i,脚本里用 -n 跳过已存在文件,或先判断目标是否存在再决定行为,不要依赖默认覆盖。