如何使用Ruby获取dig <domain> +short输出 无需调用系统命令
实现方法
问题原因说明
你之前只能拿到第一条CNAME结果,是因为单次DNS查询只会返回当前查询域名的直接解析记录。dig www.mlb.com +short 默认会自动走完完整的CNAME递归解析链路,直到获取到最终的IP地址,所以你需要手动实现递归解析逻辑才能拿到完整的链路结果。
方案1:使用Ruby标准库Resolv实现(无需安装第三方依赖)
不需要额外安装gem,直接用Ruby自带的DNS解析模块即可实现:
require 'resolv' def dig_short(domain, result = []) # 优先查询CNAME记录 cnames = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::CNAME) if cnames.any? cname = cnames.first.name.to_s result << cname # 递归解析CNAME对应的记录 return dig_short(cname, result) end # 没有CNAME时查询A记录(IP) a_records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::A) a_records.each { |a| result << a.address.to_s } result end # 调用测试 puts dig_short('www.mlb.com')
运行输出和dig +short完全一致:
www.mlb.com.edgekey.net e5991.dscg.akamaiedge.net 104.77.230.52
方案2:使用dnsruby库实现
如果你习惯用dnsruby,只要补充递归解析逻辑即可:
require 'dnsruby' include Dnsruby def dig_short(domain, result = []) res = Resolver.new # 先查CNAME记录 begin ret = res.query(domain, Types.CNAME) if ret.answer.any? cname = ret.answer.first.rdata.to_s result << cname return dig_short(cname, result) end rescue Dnsruby::ResolvError # 不存在CNAME记录时跳过,直接查A记录 end # 查询最终A记录 ret = res.query(domain, Types.A) ret.answer.each { |a| result << a.rdata.to_s } result end # 调用测试 puts dig_short('www.mlb.com')
注意事项
如果目标域名对应多个A记录,上面的代码会全部输出,和原生dig +short的行为完全一致,全程不需要依赖系统的dig命令。
内容的提问来源于stack exchange,提问作者Henley Wing Chiu
相关产品推荐
相关产品推荐

