通过SSH按指定列表批量下载远程服务器文件夹,解决scp、rsync执行报错问题
问题根因分析
- 循环逻辑错误:
for i in "list.txt"是把字符串list.txt本身作为循环变量值,并没有读取文件内存储的文件夹列表。之前使用scp时源路径直接写了父目录没有拼接变量,所以直接下载了父目录下的所有内容。 - 路径指向错误:你需要下载的是远程SSH主机的文件,rsync/scp默认读取本地路径,所以会在你当前操作的本地机器查找对应路径,自然返回找不到文件的报错。
正确实现方案
前提要求:list.txt每行存储一个待下载的文件夹名称,无多余空行、前后空格。
方案1:rsync原生实现(更推荐,无需循环,性能更高)
rsync本身支持直接读取文件列表批量拉取,无需额外写循环,命令如下:
rsync -Pavizuh --files-from=./list.txt 远程SSH用户名@远程主机IP:/远程源文件夹父路径/ /本地目标存储路径/
如果你的SSH使用非默认22端口,可以额外加参数指定端口:
rsync -Pavizuh -e 'ssh -p 你的SSH端口号' --files-from=./list.txt 远程SSH用户名@远程主机IP:/远程源文件夹父路径/ /本地目标存储路径/
方案2:修正后的循环写法(适合需要对单个文件夹做额外逻辑处理的场景)
如果需要循环处理每个文件夹,用while read读取文件内容,避免文件夹名带空格时出现异常:
while IFS= read -r i || [[ -n $i ]]; do rsync -Pavizuh 远程SSH用户名@远程主机IP:/远程源文件夹父路径/"$i" /本地目标存储路径/ done < list.txt
IFS=作用是保留行首尾的空格-r作用是避免路径中的转义字符被错误解析|| [[ -n $i ]]作用是兼容list.txt最后一行没有换行符的场景
注意事项
- 确保
list.txt中的文件夹名称和远程主机上的名称完全一致,大小写匹配 - 确认远程源文件夹父路径正确,添加远程主机前缀后rsync会直接从远程主机拉取对应路径内容,不会再查询本地路径
内容的提问来源于stack exchange,提问作者Daniell
相关产品推荐
相关产品推荐

