Ruby中使用scp通配符下载轮转日志文件失败求助
问题:net-scp无法通过通配符下载轮转日志文件
我使用net/ssh与net-scp工具,原本可以通过以下代码成功从服务器下载指定日志文件到本地:
log_list = ["ini.log", "syslog.log", "network.log"] fetch(log_list) def fetch(fetchlogs) root_cli do |ssh| fetchlogs.each do |testlog| source= "/var/log/logfiles/#{testlog}" destination = "/home/Documents/testdir/" ssh.scp.download!(source,destination) rescue Exception => e info "#{fetch} is not a valid file ==++==++ " end end end
现在这些日志是轮转日志,存在如ini.log、ini.log.001、ini.log.002等多个文件,我希望下载所有相关文件。尝试在log_list中添加通配符*:
log_list = ["ini.log*", "syslog.log*", "network.log*"]
但执行后报错,提示找不到有效文件:
ini.log* is not a valid file ==++==++ syslog.log* is not a valid file ==++==++ network.log* is not a valid file ==++==++
我也尝试直接在source路径后添加*:
source = "/var/log/logfiles/#{testlog}*" pp " source #{source}" ssh.scp.download!(source,"/home/Documents/testdir/")
输出显示source路径正确,但仍出现相同错误。明明文件存在,请问是不是*字符被转义了?
解决方案
net-scp的download!方法本身不支持解析通配符——因为通配符是shell层面的功能,scp协议本身不会处理匹配逻辑。你需要先通过ssh执行shell命令,匹配出所有目标文件的路径,再逐个下载。
修改后的代码示例:
log_list = ["ini.log", "syslog.log", "network.log"] fetch(log_list) def fetch(fetchlogs) root_cli do |ssh| fetchlogs.each do |base_log| # 通过ssh执行ls命令,利用shell解析通配符,获取所有匹配的文件路径 matching_files = ssh.exec!("ls /var/log/logfiles/#{base_log}*").split("\n").reject(&:empty?) matching_files.each do |source| destination = "/home/Documents/testdir/" begin ssh.scp.download!(source, destination) rescue Exception => e info "#{source} 不是有效文件 ==++==++ " end end end end end
补充说明
- 如果服务器上的
ls输出可能包含目录(你只想下载文件),可以添加-f参数只列出文件:matching_files = ssh.exec!("ls -f /var/log/logfiles/#{base_log}*").split("\n").reject(&:empty?) - 也可以用
find命令做更精准的匹配(只找普通文件,排除目录):matching_files = ssh.exec!("find /var/log/logfiles -type f -name \"#{base_log}*\"").split("\n").reject(&:empty?)
内容的提问来源于stack exchange,提问作者Rubin
相关产品推荐
相关产品推荐

