cp -r pojie/ wpa-dictionary/pojie
# cp: cannot overwrite non-directory 'wpa-dictionary/pojie' with directory 'pojie/'
这个错误不是 cp 参数写错,而是目标路径 wpa-dictionary/pojie 已经存在一个普通文件,不是目录。
诊断
ls -ld wpa-dictionary/pojie
如果输出以 - 开头,说明是普通文件:
-rw-r--r-- 1 root root 1234 Jun 15 wpa-dictionary/pojie
如果是目录会以 d 开头:
drwxr-xr-x 2 root root 4096 Jun 15 wpa-dictionary/pojie
解决方案
方案 1:删除目标文件后再复制
rm -f wpa-dictionary/pojie
cp -r pojie wpa-dictionary/
方案 2:复制到不同名称
cp -r pojie wpa-dictionary/pojie_backup
方案 3:先移动目标文件
mv wpa-dictionary/pojie wpa-dictionary/pojie.bak
cp -r pojie wpa-dictionary/
cp 目录行为说明
cp -r src dst 的行为取决于 dst 是否存在:
| 目标是否存在 | 行为 |
|---|---|
dst 不存在 | 把 src 复制为 dst(改名) |
dst 是目录 | 把 src 整体放进 dst/src |
dst 是普通文件 | 报错:cannot overwrite non-directory |
例如:
# 目标目录 backup/ 不存在
cp -r project/ backup/
# 结果:backup/ 就是 project/ 的副本
# 目标目录 backup/ 已存在
cp -r project/ backup/
# 结果:backup/project/(嵌套了一层)
注意末尾斜杠的影响:cp -r pojie/ dst 和 cp -r pojie dst 行为可能不同(前者复制内容,后者复制整个目录)。
rsync 作为替代
目录同步推荐用 rsync,语义更清晰,且支持增量更新:
# 把 pojie/ 的内容同步到 wpa-dictionary/pojie/
rsync -av pojie/ wpa-dictionary/pojie/
# 只复制新文件,跳过已存在的
rsync -av --ignore-existing pojie/ wpa-dictionary/pojie/
# 删除目标中源没有的文件(镜像同步)
rsync -av --delete pojie/ wpa-dictionary/pojie/
rsync 在处理已存在目标时不会报上面的错误,会直接合并或覆盖。
