Shell cp报错cannot stat no such file or directory的解决方法
问题原因
当index目录为空、没有任何文件能匹配index/*通配符时,Bash默认不会把通配符展开为空,而是直接将字面字符串index/*传入for循环体。此时cp命令实际尝试复制路径为index/*的文件,这个路径不存在自然抛出cannot stat错误。之前加2>/dev/null不生效,基本是重定向位置写错,或是没有从根源阻止无效的cp命令执行。
另外原脚本存在一处逻辑笔误:cp的目标路径写死为.target/file,没有使用提取出的$file变量,会导致所有复制的文件都被覆盖为.target下名为file的单文件/目录,复制多文件时会出问题,记得修正为.target/$file;如果.target目录提前不存在,还要先执行mkdir -p .target创建目录。
可行修复方案
方案1:开启nullglob选项(最优方案)
开启Bash内置的nullglob选项后,通配符匹配不到文件时会直接展开为空,for循环不会执行任何迭代,从根源避免无效cp调用,不需要额外屏蔽错误:
# 开启nullglob配置 shopt -s nullglob for files in index/* do file=$(echo "$files" | cut -d'/' -f2) cp -r "$files" ".target/$file" done # 脚本执行完可关闭nullglob,避免影响后续其他逻辑 shopt -u nullglob
方案2:循环内判断源文件是否存在
如果不想修改Shell全局配置,可以在每次执行cp前判断当前源路径是否真实存在,匹配到字面量index/*时直接跳过:
for files in index/* do # 路径不存在则跳过本次循环 [ -e "$files" ] || continue file=$(echo "$files" | cut -d'/' -f2) cp -r "$files" ".target/$file" done
方案3:正确配置错误重定向(不推荐)
如果仅想屏蔽错误输出,需要把重定向规则写在cp命令的末尾:
for files in index/* do file=$(echo "$files" | cut -d'/' -f2) cp -r "$files" ".target/$file" 2>/dev/null done
注意:该方案会无差别屏蔽cp命令的所有错误输出,包括权限不足、磁盘写入失败等真实运行异常,会提升后续问题排查难度,非必要不使用。
内容的提问来源于stack exchange,提问作者User21749
相关产品推荐
相关产品推荐

