追加読書

追加読書

40,000行のドメイン名を含む大容量ファイルがあります。そのファイルを読み取り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では1つ、Knot DNSでは1つ、djbwaresでは1つ)は、人間が読める形式で情報を印刷して退屈な作業を実行する必要があります。リストが欲しい

ISCdigとKnot DNSにはこれを改善するオプションがkdigありますが(/の一般的な出力+shortも含む)、一度に1つのドメイン名からのみ呼び出すことができるので、シェルスクリプトのループと少なくとも40,000のプロセスが必要です。職業。 (ここで1つの答えには約160,000のプロセスがあります。)digkdig

dnsipもう一つのツールは、djbdnsツールセットの一部であるDaniel J. Bernsteinのツールです。xargsツールは複数のドメイン名パラメータを使用できるため、必要な操作は1行を使用することです。

%猫ドメイン名。リスト
unix.stackexchange.com
freebsd.org
cr.yp.to
%
%xargs dnsip <ドメイン名。リスト
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完全修飾されていないドメイン名を使用したい場合のためのツールがあります。

%猫ドメイン名。リスト
Unix
フリーソフトウェア
暗号通貨
%
%xargs dnsipq <ドメイン名。リスト
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アドレスを次のアドレスとスペースで区切ります。

#!/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

関連情報