nslookup awk を実行して「回答」を表示するファイルを検索する

nslookup awk を実行して「回答」を表示するファイルを検索する

現在、多数のホストで 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 [...] )adighead -n1unix.stackexchange.com

これを変数に取り出す理由は、前述したように、単純なパラメータ拡張トリックを使用して、空の文字列の代わりに「解決されませんでした」というテキストを提供できるようにするためです。

声明で要求されたとおりecho具体的に拡張します。

echo -e "$h\t${a:-Did_Not_Resolve}"
  • スイッチは私が使用するものを-e示していますechoeスケープシーケンス。この場合、\tと組み合わせると-eTabリテラルのエスケープされた ではなく になりますt
  • $hは、予想どおり、変数の内容に単純に置き換えられますh
  • \tは、前述したように、タブになります。
  • ${a:-Did_Not_Resolve}ああ、ここに魔法があります。 bashパラメータ展開を行う際に、プロセスの一部として少しイントロスペクションを行う機能があります。構文は${var:-default}変数の内容に展開されますvar または、それが未設定または null の場合は、提供された置換 (この例では 、defaultまたはここでの実際の使用例ではDid_Not_Resolve) になります。詳細については、マニュアル ページの「パラメータ展開」というセクションを参照してくださいbash

最終結果として、各行にホスト名、a Tab、アドレス(ある場合)またはテキストDid_Not_Resolve(ない場合は)が次の順序で出力されます。

関連情報