
我目前正在運行一個腳本,該腳本在一堆主機上使用 nslookup,然後使用 awk 將所需的行列印到表中。我將一行列印到 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 個在左側欄中顯示“answer:”,而主機名稱出現在右側。像這樣:
Host IP
answer: hostname
這在整個結果中隨機出現,我無法弄清楚,因為 nslookup 在任何地方都沒有單字“answer:”,導致腳本意外 awk。
這是我的腳本供參考:
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
是一個比 is 更易於腳本編寫的 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
在子 shell ( $( dig [...] )
) 中運行,因為我捕獲其輸出並將其分配給變數a
(對於“地址”)。我正在dig
透過管道傳輸某些主機的輸出head -n1
(例如主機unix.stackexchange.com
返回多個 IP 位址;為了簡單起見,我只獲取第一個。
將其拉出到變數中的原因是,我們可以使用簡單的參數擴展技巧來提供「未解析」文字來代替空字串,如本文前面所述。
具體按照聲明中的要求進行擴展echo
:
echo -e "$h\t${a:-Did_Not_Resolve}"
- 開關
-e
告訴echo
我將使用e景觀序列。在這種情況下,我使用的\t
是,當與 結合時-e
,變成 aTab而不是文字轉義t
。 $h
正如您所期望的,只是替換為變數 的內容h
。\t
如前面所解釋的,成為一個選項卡。${a:-Did_Not_Resolve}
。啊,這就是神奇的地方。bash
作為過程的一部分,在進行參數擴展時能夠進行一些內省。語法${var:-default}
擴展到變數的內容var
或者,如果未設定或為 null,則提供的替換(在此範例中為 ;default
或在此處的實際用例中為Did_Not_Resolve
)。您可以在bash
手冊頁中標有“參數擴展”的部分中找到有關此內容的更多詳細資訊。
最終結果是在每一行上按以下順序輸出主機名稱、 aTab以及位址(如果有)或文字Did_Not_Resolve
(如果沒有)。