
現在、多数のホストで nslookup を使用し、次に awk を使用して必要な行をテーブルに出力するスクリプトを実行しています。1 行を file1 に出力し、別の行を file2 に出力してから、を使用してpaste file1 file2 >> file3
このテーブルを作成しています。
表は次のようになります
Host IP
name 10.10.10.10
name 10.10.10.10
name 10.10.10.10
ほとんどの場合、これはうまくいきます。しかし、何らかの理由で、160 件の結果のうち約 20 件で、左の列に「回答:」が表示され、ホスト名が右に表示されます。次のようになります。
Host IP
answer: hostname
これは結果全体でランダムに表示され、nslookup にはスクリプトが誤って awk を実行するための「answer:」という単語がどこにも含まれていないため、原因がわかりません。
参考までに私のスクリプトを以下に示します。
hosts='hosts.list'
filelines=`cat $hosts`
Empty_Containers(){
truncate -s 0 tmp.txt
truncate -s 0 file1
truncate -s 0 file2
}
for h in $filelines ;
do
Empty_Containers
nslookup $h > tmp.txt
if grep -q "NXDOMAIN" tmp.txt
then
cat tmp.txt | awk 'FNR ==4 {print$5}' > file1
echo "Did_Not_Resolve" > file2
paste file1 file2 >> i.txt
else
cat tmp.txt | awk 'FNR ==4 {print$2}' > file1
cat tmp.txt |awk 'FNR ==5 {print$2}' > file2
paste file1 file2 >> i.txt
fi
cat i.txt | column -t 2 i.txt
done
答え1
ホスト名と IP アドレスのテーブルを作成することだけが目的であり、 を使用することを特に気にしない場合はnslookup
、簡単なループで目的の出力を作成できたようですfor .. echo
。
for h in $( cat hosts.list ); do
a=$(dig +short $h | head -n1)
echo -e "$h\t${a:-Did_Not_Resolve}"
done
dig
は よりもスクリプト作成に少しだけ優しい DNS ツールですがnslookup
、 オプションを使用すると+short
出力がさらにきれいになります。レコードがない要求の出力は空の文字列なので、レコードがない場合には組み込みのbash
デフォルト パラメータ展開 ( ${var:-default}
) を使用して、 という「デフォルト」の回答を返すように処理しますDid_Not_Resolve
。
$ dig www.example.com
; <<>> DiG 9.10.6 <<>> www.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23579
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;www.example.com. IN A
;; ANSWER SECTION:
www.example.com. 20308 IN A 93.184.216.34
;; Query time: 28 msec
;; SERVER: 172.28.8.1#53(172.28.8.1)
;; WHEN: Fri Jun 01 12:02:27 MST 2018
;; MSG SIZE rcvd: 60
$ dig +short www.example.com
93.184.216.34
最終的な収量は次の出力になります。
www.example.com 93.184.216.34
www.google.com 172.217.14.68
host.doesnotexist.tld Did_Not_Resolve
unix.stackexchange.com 151.101.129.69
の代替として、次の方法dig
もありますhost
。
$ for h in $(cat hosts.list); do host $h; done
www.example.com has address 93.184.216.34
www.example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946
www.google.com has address 216.58.193.196
www.google.com has IPv6 address 2607:f8b0:4007:80d::2004
Host host.doesnotexist.tld not found: 3(NXDOMAIN)
unix.stackexchange.com has address 151.101.129.69
unix.stackexchange.com has address 151.101.1.69
unix.stackexchange.com has address 151.101.65.69
unix.stackexchange.com has address 151.101.193.69
以下のコメントの質問に回答します。
に使用する唯一のオプションdig
は で+short
、これは出力を指定されたホストの IP アドレスか、それ以外の場合は空の文字列に減らします。出力をキャプチャして変数 (「アドレス」用) に割り当てるため、dig
サブシェル ( ) で実行します。一部のホスト (ホストなど) は複数の IP アドレスを返すため、の出力をパイプで渡しています。簡単にするために、最初のアドレスを取得するだけです。 $( dig [...] )
a
dig
head -n1
unix.stackexchange.com
これを変数に取り出す理由は、前述したように、単純なパラメータ拡張トリックを使用して、空の文字列の代わりに「解決されませんでした」というテキストを提供できるようにするためです。
声明で要求されたとおりecho
具体的に拡張します。
echo -e "$h\t${a:-Did_Not_Resolve}"
- スイッチは私が使用するものを
-e
示していますecho
eスケープシーケンス。この場合、\t
と組み合わせると-e
、Tabリテラルのエスケープされた ではなく になりますt
。 $h
は、予想どおり、変数の内容に単純に置き換えられますh
。\t
は、前述したように、タブになります。${a:-Did_Not_Resolve}
ああ、ここに魔法があります。bash
パラメータ展開を行う際に、プロセスの一部として少しイントロスペクションを行う機能があります。構文は${var:-default}
変数の内容に展開されますvar
または、それが未設定または null の場合は、提供された置換 (この例では 、default
またはここでの実際の使用例ではDid_Not_Resolve
) になります。詳細については、マニュアル ページの「パラメータ展開」というセクションを参照してくださいbash
。
最終結果として、各行にホスト名、a Tab、アドレス(ある場合)またはテキストDid_Not_Resolve
(ない場合は)が次の順序で出力されます。