在lftp中使用mget匹配含通配符的文件名失败问题排查
lftp mget用变量拼接通配符无法下载的原因及解决办法
问题场景
要通过lftp的mget命令下载远程服务器上命名格式为abc_yyyymmdd_hhmmss.csv的文件,目标是匹配指定日期的所有文件(即abc_20221202_*.csv)。脚本通过变量拼接出带通配符*的文件名后,能检测到文件存在,但无法完成下载;而直接硬编码完整文件名(或硬编码带*的格式)时,下载完全正常。
核心原因
问题出在shell的通配符扩展优先级:
当脚本里执行mget $Filename时,shell会先尝试在本地目录扩展通配符*,而不是把带*的字符串直接传给lftp去处理远程服务器的文件匹配。
- 如果本地目录恰好有匹配
abc_20221202_*.csv的文件,shell会把*替换成本地的文件名列表,传给lftp后,lftp会去远程找这些本地文件名,自然找不到; - 如果本地没有匹配文件,默认情况下shell会把
abc_20221202_*.csv原样传给lftp,但此时通配符可能因为没有被正确识别,导致lftp无法解析远程的文件匹配规则。
解决办法
1. 给变量加引号,阻止shell本地扩展
修改here-doc中的mget命令,给变量加上双引号,让shell把带通配符的字符串完整传给lftp,由lftp在远程解析通配符:
File=abc_ Date=20221202 Filename="$File$Date"_*.csv conn=$(lftp $protocol://$user:$password@$sftp_server -p $port <<EOF>/error.log cd $path mget "$Filename" EOF)
2. 直接在命令中拼接变量,保留通配符
不需要单独定义Filename变量,直接在mget命令里拼接日期变量,让shell只扩展$Date,*原样保留给lftp:
Date=20221202 conn=$(lftp $protocol://$user:$password@$sftp_server -p $port <<EOF>/error.log cd $path mget abc_${Date}_*.csv EOF)
3. 临时关闭shell的通配符扩展
在执行lftp命令前,临时关闭shell的glob扩展功能,执行完成后再恢复:
File=abc_ Date=20221202 Filename="$File$Date"_*.csv set -f # 关闭通配符扩展 conn=$(lftp $protocol://$user:$password@$sftp_server -p $port <<EOF>/error.log cd $path mget $Filename EOF) set +f # 恢复通配符扩展
内容的提问来源于stack exchange,提问作者likeGreen
相关产品推荐
相关产品推荐

