Windows下Bash脚本多目录文件传输至Linux的索引匹配问题
解决Windows Bash脚本中scp跨服务器文件传输的索引匹配问题
问题根源
你原来的脚本中,初始化源数组时使用了带通配符*的路径,Bash会自动将通配符展开为目录下的所有文件,导致源数组的元素数量远多于目标数组,循环时索引完全错位,最终文件被传到错误的目录。
解决方案
将源目录路径和目标目录路径作为成对元素处理,避免通配符提前展开。具体做法是:用两个平行数组分别存储源目录(不带*)和目标目录,循环每一对目录,在循环内部处理该目录下的所有文件传输,确保索引一一对应,同时不复制目录结构。
修改后的脚本
# 定义源目录列表(直接指向目录,不带通配符) source_dirs=( "/c/Users/adbls/Documents/HR" "/c/Users/adbls/Documents/Abschluss" "/c/Users/adbls/Documents/GL" ) # 定义对应Linux服务器的目标目录列表 target_dirs=( "/home/sara.blatter/HR/" "/home/sara.blatter/Abschluss/" "/home/sara.blatter/GL/" ) # 确保已定义远程用户和主机变量 User="sara.blatter" remoteHost="你的Linux服务器IP或主机名" # 循环处理每一对目录 for i in "${!source_dirs[@]}"; do local_src="${source_dirs[$i]}" remote_target="${User}@${remoteHost}:${target_dirs[$i]}" # 检查源目录下是否有文件,避免空目录时scp报错 if compgen -G "${local_src}/*" > /dev/null; then # 传输该目录下所有文件到对应目标目录,不携带源目录结构 scp "${local_src}"/* "${remote_target}" # 如果需要传输后删除源文件,取消下面注释 # rm "${local_src}"/* fi done
关键说明
- 索引匹配:源数组和目标数组长度完全一致,循环时索引
i能精准对应每一对目录,不会出现错位。 - 避免目录结构复制:
${local_src}/*会展开为目录下的所有文件,scp直接传输文件本身,不会将源目录的层级带到目标服务器。 - 空目录处理:通过
compgen -G检查目录下是否存在文件,避免空目录时scp抛出"No such file or directory"错误。
额外注意事项
- 配置SSH免密登录:在Windows Bash中执行
ssh-keygen生成密钥对,将公钥复制到Linux服务器的~/.ssh/authorized_keys文件中,确保任务计划程序运行时无需手动输入密码。 - 任务计划程序配置:选择Git Bash的执行路径(如
C:\Program Files\Git\bin\bash.exe),将脚本路径作为参数传入,确保脚本能正常执行。
内容的提问来源于stack exchange,提问作者habibiblockberg
相关产品推荐
相关产品推荐

