Git Bash中脚本内find与cp命令失效,终端单独执行正常求排查
问题:脚本循环无法复制文件,但单独执行命令有效?
问题场景
当前目录下有list.txt文件,内容如下:
Container ID W1412886 W1402878 W1402821 W1402789 W1402792 ...
同时存在若干子文件夹,其中包含文件名以列表中ID开头的文件。编写的Bash脚本可以正常输出Processing Container ID: XXX,但无法完成文件复制;而在终端单独执行如下命令却能正常工作:
find . -type f -name W1412886* -exec cp {} FINAL \;
使用环境为Git Bash。
原因分析
1. Windows格式换行符导致变量包含隐藏回车符
这是Git Bash环境下最常见的原因:list.txt采用Windows的CRLF(\r\n)换行格式,而Bash默认处理Unix的LF(\n)换行。当read命令读取每行ID时,会把末尾的\r(回车符)一并存入container_id变量中。此时find实际在查找以[ID]\r开头的文件,自然无法匹配到目标文件。
2. 通配符未被正确传递给find
脚本中${container_id}*未用引号包裹,虽然终端中shell会将不匹配的通配符原样传递给find,但在Git Bash的特定配置下,可能出现异常展开,导致find收到的参数不是预期的通配符模式。
解决方法
方案一:处理换行符问题
方式1:读取时过滤回车符
修改while循环中的read命令,明确指定换行符为LF,过滤掉回车符:
tail -n +2 "$container_file" | while IFS=$'\r\n' read -r container_id || [[ -n "$container_id" ]]; do
方式2:转换文件为Unix格式
在Git Bash中执行以下命令,将list.txt转换为Unix换行格式:
dos2unix list.txt
方案二:正确传递通配符给find
将find命令的-name参数用双引号包裹,确保通配符被原样传递给find,避免shell提前展开:
find . -type f -name "${container_id}*" -exec cp {} "$destination_folder" \;
建议同时使用方案一和方案二,彻底解决问题。
内容的提问来源于stack exchange,提问作者Manolo Dominguez Becerra
相关产品推荐
相关产品推荐

