You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 08:42:03