Mac OS使用cp -r/cp -R命令无法复制隐藏文件如何解决
隐藏文件未复制的问题,和cp命令的-r/-R递归参数、sudo权限都没有关系,根源是Shell的通配符默认匹配规则:
- 命令中使用了
*通配符时,Shell会在执行cp前,先把*展开为当前目录下所有符合匹配规则的文件/目录路径,再把展开后的路径列表传给cp处理 - 包括bash、zsh在内的macOS默认Shell,默认配置下
*通配符不会匹配以.开头的隐藏文件/目录,因此.git、.gitignore、.DS_Store这类隐藏项根本没有被传递给cp命令,自然不会被复制。
注:macOS系统中
cp命令的-r和-R参数效果完全一致,都是递归复制目录,二者的差异不会导致这个问题。
以下三种方法都可以完整复制包含隐藏文件在内的所有目录内容,按需选择即可:
方法1:直接引用当前目录路径,不使用
*通配符(最简便,无需修改配置)
执行以下命令,其中.代表当前工作目录,cp会递归复制目录下所有内容(包含全部隐藏项):cp -R . ../otherfolder注意:如果目标路径
../otherfolder已经存在,建议在路径末尾加斜杠写为cp -R . ../otherfolder/,避免把当前目录整体嵌套复制到目标目录下的子文件夹中。方法2:开启Shell的dotglob选项,让
*匹配隐藏文件
如果你习惯用*通配符,可以临时开启通配符匹配隐藏文件的配置:- 如果你使用bash作为默认Shell,先执行:
shopt -s dotglob - 如果你使用zsh作为默认Shell,先执行:
setopt dotglob
配置生效后,再执行常规复制命令即可正常复制隐藏文件:
cp -R * ../otherfolder复制完成后可以关闭该配置恢复默认行为,bash执行
shopt -u dotglob,zsh执行unsetopt dotglob即可。- 如果你使用bash作为默认Shell,先执行:
方法3:使用
rsync命令(更适合目录同步场景)rsync是类Unix系统自带的目录同步工具,默认就会复制隐藏文件,还支持保留文件权限、时间戳、增量复制等能力,命令如下(末尾斜杠不要省略):rsync -av . ../otherfolder/其中
-a为归档模式,会递归复制所有内容并保留文件原有属性,-v为verbose模式,会输出复制进度方便排查问题。
避坑提醒:不要使用网上流传的
cp -R * .* ../otherfolder写法,.*会匹配到代表当前目录的.和代表上级目录的..,执行后会把上级目录的所有内容也复制到目标路径,极易造成文件混乱。
内容的提问来源于stack exchange,提问作者Devin Dixon

