cp -r 复制文件夹报“cannot overwrite directory”因目标目录已存在且cp默认不覆盖;需rm -rf后复制或改用rsync -a --delete;权限时间戳丢失需加-p;符号链接默认被跟随,保留链接需-d;大目录无进度提示应加-v或换rsync。

cp -r 复制文件夹时提示 “cannot overwrite directory”
这是最常踩的坑:目标路径已存在同名目录,cp -r 默认拒绝覆盖——它不是“覆盖目录”,而是试图把源目录“塞进”已有目录里,结果报错。
常见场景:反复运行脚本想刷新备份,或误以为 cp -r 像 rsync 那样自动处理冲突。
- 解决方法:加
-f参数无效(cp -rf仍不覆盖已有目录);必须先删目标再复制:rm -rf /path/to/dest && cp -r /path/to/src /path/to/dest
- 更安全的做法是用
rsync -a --delete,但注意--delete会清空目标中多余文件,务必确认路径无误 - 如果只是想“更新内容”,
cp -r本身不支持增量,别硬扛,换rsync
cp -r 拷贝后权限/时间戳全变了
cp -r 默认不保留所有权、权限位和修改时间,尤其在跨用户或跨文件系统复制时明显——比如从 root 拷到普通用户家目录,所有者变成当前用户,chmod 设置的执行位可能丢失。
- 加
-p参数可保留权限、所有者、时间戳:cp -rp /src/dir /dst/dir
-
-p等价于--preserve=mode,ownership,timestamps;若只要时间戳,可用--preserve=timestamps - 普通用户执行
-p时无法恢复 root 所有者,会静默忽略 ownership,只保留 mode 和 timestamps
cp -r 在符号链接上的行为很反直觉
默认情况下,cp -r 遇到符号链接会“跟随链接”复制目标文件/目录,而不是复制链接本身——这跟 ls -l 看到的不一样,容易误判源结构。
- 要复制符号链接本身(即创建一个新链接,指向相同路径),必须加
-d或--no-dereference:cp -r -d /src/dir /dst/dir
- 混合使用:想递归复制但保留所有链接,用
cp -rd;想跟随部分链接、保留部分,cp -r不支持,得手动处理或改用tar中转 - 注意:
-d在某些旧版 busybox 中不可用,优先检查cp --help | grep dereference
大文件夹用 cp -r 卡住没反馈
cp -r 是哑命令,不输出进度、不显示当前拷贝哪个文件,遇到几十 GB 的目录时容易以为卡死。
- 加
-v可逐个打印文件路径,但输出爆炸,不适合管道或日志分析 - 更实用的是用
rsync -av --progress替代,有实时速度、剩余时间、已拷比例 - 若坚持用
cp,可配合pv(需额外安装):tar -cf - /src/dir | pv | tar -xf - -C /dst
,但要注意 tar 对绝对路径的处理
实际操作前多看一眼 ls -ld /dst/dir,确认目标是否存在、是否为空、权限是否允许写入——很多“复制失败”根本不是 cp 的问题,而是目标路径状态没理清。










