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のプロセスがあります。)dig
kdig
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 %
追加読書
- https://unix.stackexchange.com/a/557555/5132
- ダニエルJ.バーンスタイン(1999)。
dnsip
。DJBウェア。 - ダニエルJ.バーンスタイン(1999)。
dnsipq
。DJBウェア。 - https://unix.stackexchange.com/a/446293/5132
答え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