进一步阅读

进一步阅读

我有一个大文件,其中包含 40000 行域名。我想读取该文件并使用dig(或其他方式)在 DNS 中查找域名的 IP 地址,并将它们打印到另一个文件中。

我该怎么做呢?

编辑:一直在使用一些建议的解决方案对此进行测试。大部分内容都是这样:

#!/bin/bash
> ips.txt
cat test.txt | while read host; do
    ip=$(getent hosts "$host")
    if [ $? -ne 0 ]; then
        echo "Host $host was not resolved.";
        continue
    fi
    ip=$(echo "$ip" | awk '{ print $1 }')
    echo "Host: $host, IP: $ip" >> ips.txt
done

这会生成一个空文件。不知道为什么这不起作用。

我尝试了另一种解决方案:

for host in 0.accountkit.com 0.bigclicker.me 0.cdn.ddstatic.com 0.facebook.com 0.fls.doubleclick.net 0.hiveon.net 0.mining.garden
do
    # get ips to host using dig
    ips=($(dig "$host" a +short | grep '^[.0-9]*$'))
    for ip in "${ips[@]}";
    do
        printf 'allow\t\t%s\n' "$ip"
    done
done > allowedip.txt

这将打印 ip 地址,但问题是我需要从文件而不是脚本本身读取 DNS 名称。

答案1

很高兴你说这dig不是一个要求,因为它不是完成这项工作的最佳工具。

像命令这样的工具host(许多操作系统有 3 种实现方式:ISC 的 BIND 中的一种、Knot DNS 中的一种和 djbwares 中的一种)以人类可读的形式打印信息,并且必须进行繁琐的后处理如果需要一个简单的机器可读列表,则可以去除无用的信息。

ISCdig和 Knot DNSkdig有一个+short选项,可以对此进行改进(以及dig/的普通输出kdig),但仅限于一次在一个域名上调用,需要 shell 脚本中的循环和至少 40,000 个进程来完成这项工作。 (这里的一个答案大约有 160,000 个进程。)

另一个工具是 Daniel J. Bernstein 的dnsip,它是他的 djbdns 工具集的一部分。您想要做的是单行 via xargs,因为该工具可以采用多个域名参数:

%cat 域名.list
unix.stackexchange.com
freebsd.org
cr.yp.to
%
%xargs dnsip < 域名.list
151.101.65.69 151.101.193.69 151.101.1.69 151.101.129.69
96.47.72.84
131.193.32.109 131.193.32.108
%

这在一定程度上减少了进程数。 (快速粗略测试表明,减少了 3 个数量级。我的 40,000 个域名测试列表仅产生了 9 个dnsip进程。)

dnsipq当您想要使用非完全限定域名时,有一个工具:

%cat 域名.list
UNIX
自由软件
加密货币
%
%xargs dnsipq < 域名.list
unix.stackexchange.com 151.101.1.69 151.101.193.69 151.101.65.69 151.101.129.69
freebsd.stackexchange.com 151.101.65.69 151.101.193.69 151.101.1.69 151.101.129.69
crypto.stackexchange.com 151.101.1.69 151.101.129.69 151.101.193.69 151.101.65.69
%

进一步阅读

答案2

另一个循环。该命令从 中读取主机名列表,hosts并将每个主机名及其零个或多个 IPv4 地址写入到 中ips。我使用制表符 ( ) 将主机与其 IP 地址列表分隔开\t,每个 IP 地址与下一个 IP 地址之间用空格分隔:

#!/bin/bash
while IFS= read -r host
do
    if [[ -n "$host" ]]
    then
        ips=$(dig +short "$host" | grep '^[[:digit:].]*$' | xargs)
        printf "%s\t%s\n" "$host" "$ips"
    fi
done <hosts >ips

示例数据:

源文件hosts

bbc.co.uk
google.co.uk

结果文件ips

bbc.co.uk       151.101.192.81 151.101.128.81 151.101.64.81 151.101.0.81
google.co.uk    216.58.213.3

答案3

在单个命令行或小型 bash 脚本中:

while IFS= read -r Domainname; do [ -n "$Domainname" ] && echo "$Domainname: $(dig +short "$Domainname" | tr '\n' ' ')"; done < domainlist.csv

domainlist.csv这会将包含域名的文件读取到while循环中。主体仅输出所有非空行。

答案4

这将获取文件 中的每一行hosts.txt,在主机上执行 DNS 查找并将结果 IP 地址(与主机名一起)写入ips.txt.请记住,它不会进行并行查找来减少时间,也不会处理无效输入。而且它不处理多个 IP 地址。

至于错误,如果主机名未解析,它将在屏幕上打印错误。不会ips.txt为该主机写入任何内容。

#!/bin/bash
> ips.txt
cat hosts.txt | while read host; do
    ip=$(getent hosts "$host")
    if [ $? -ne 0 ]; then
        echo "Host $host was not resolved.";
        continue
    fi
    ip=$(echo "$ip" | awk '{ print $1 }')
    echo "Host: $host, IP: $ip" >> ips.txt
done

相关内容