跳转到内容

cp

cp(copy)用于复制文件和目录。默认行为有三个要留意的地方:不递归、不保留属性、遇到同名文件直接覆盖且不提示。

Terminal window
cp [选项] 源文件 目标文件
cp [选项] 源文件... 目标目录

目标是已存在的目录时,源按原名复制进去 给多个源时,最后一个参数必须是已存在的目录 复制目录必须带 -r,否则报 omitting directory

选项 说明
-r 递归复制目录(recursive),-R 等价
-a 归档模式(archive),等于 -dR --preserve=all,备份场景基本只用它
-p 保留修改时间、权限、属主(preserve)
-d 软链接照抄成软链接,不跟随到目标文件
-i 覆盖前提示(interactive)
-n 目标已存在就跳过,不提示(no-clobber)
-f 目标打不开时先删掉再重建(force)
-u 只在源比目标新、或目标不存在时才复制(update)
-v 打印每一次复制(verbose)
-l 建硬链接代替复制(link)
-s 建软链接代替复制(symbolic)
--preserve=<列表> 指定保留哪些属性:mode、ownership、timestamps、links、xattr、all

1. 复制文件

Terminal window
cp a.txt b.txt # 复制成 b.txt
cp a.txt /tmp/ # 复制进 /tmp/,保持原名
cp a.txt b.txt /tmp/ # 多个源,最后一个必须是已存在的目录

2. 复制目录:目标存不存在决定结果

Terminal window
cp -r src dst

dst 不存在:新建 dst,内容与 src 相同 dst 已存在:变成 dst/src,多套了一层

想把 src 里面的东西倒进 dst,两种写法都行:

Terminal window
cp -r src/. dst/
cp -r src/* dst/ # 漏掉隐藏文件,通常不是你要的

src/. 是目录自身的引用,隐藏文件一起走 src/* 交给 shell 展开,默认不匹配 . 开头的文件

3. 备份要用 -a

Terminal window
cp -a /etc/nginx /backup/

默认的 cp 会把时间戳刷成当前时间、按 umask 重设权限、把软链接复制成实体文件 -a 等于 -dR --preserve=all,原样搬过去

4. 只复制变化的文件

Terminal window
cp -ru src/ dst/

-u 比较修改时间,源不比目标新就跳过 cp 不会删除目标里多余的文件,真要做目录同步用 rsync

5. 避免误覆盖

Terminal window
cp -i a.txt b.txt # 覆盖前问一句
cp -n a.txt b.txt # 已存在就跳过

不少发行版把 cp 别名成了 cp -i,交互下看着安全,脚本里却不生效 脚本里想绕开别名,写 \cp 或 command cp