
Atualmente, estou executando um script que usa nslookup em vários hosts e, em seguida, usa awk para imprimir as linhas desejadas em uma tabela. Estou imprimindo uma linha no arquivo1 e outra no arquivo2 e usando paste file1 file2 >> file3
para produzir esta tabela.
A mesa fica assim
Host IP
name 10.10.10.10
name 10.10.10.10
name 10.10.10.10
Na maior parte, isso está funcionando. Mas, por alguma razão, cerca de 20 dos meus 160 resultados estão recebendo "resposta:" na coluna da esquerda e o nome do host aparece na direita. Assim:
Host IP
answer: hostname
Isso está aparecendo aleatoriamente nos resultados e não consigo descobrir porque o nslookup não contém a palavra "resposta:" em nenhum lugar para que o script seja ativado acidentalmente.
Aqui está meu script para referência:
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
Responder1
Se o seu objetivo desejado é apenas criar uma tabela de nomes de host e endereços IP, e você não se importa particularmente em usar nslookup
, aparentemente consegui criar a saída desejada com um for .. echo
loop rápido:
for h in $( cat hosts.list ); do
a=$(dig +short $h | head -n1)
echo -e "$h\t${a:-Did_Not_Resolve}"
done
dig
é uma ferramenta DNS um pouco mais amigável para scripts do que o nslookup
, usar a +short
opção torna a saída ainda mais limpa. A saída de uma solicitação para a qual não há registro é uma string vazia, então eu uso a expansão de parâmetro padrão integrada bash
( ${var:-default}
) para lidar com o caso de nenhum registro fornecendo uma resposta "padrão" de 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
O rendimento final é este resultado:
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
Uma alternativa dig
também é 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
Respondendo às perguntas do comentário abaixo:
A única opção que uso dig
é +short
, que reduz a saída para o endereço IP do host fornecido ou para uma string vazia. Eu corro dig
em um subshell( $( dig [...] )
) porque estou capturando sua saída e atribuindo-a à variável a
(para "endereço"). Estou canalizando a saída dig
enquanto head -n1
alguns hosts (como o host unix.stackexchange.com
retornam vários endereços IP; por uma questão de simplicidade, simplesmente pego o primeiro.
A razão pela qual isso está sendo colocado em uma variável é para que possamos usar um truque simples de expansão de parâmetro para fornecer o texto "Não foi resolvido" no lugar de uma string vazia, conforme descrito anteriormente aqui.
Expandindo conforme solicitado especificamente na echo
declaração:
echo -e "$h\t${a:-Did_Not_Resolve}"
- O
-e
switch informaecho
que irei usaresequências de escape. Nesse caso, estou usando\t
which, quando combinado com-e
, torna-se Tabum escape em vez de literalt
. $h
é, como seria de esperar, simplesmente substituído pelo conteúdo da variávelh
.\t
, conforme explicado anteriormente, torna-se uma guia.${a:-Did_Not_Resolve}
. Ah, é aqui que está a mágica.bash
tem a capacidade, ao fazer expansão de parâmetros, de fazer uma pequena introspecção como parte do processo. A sintaxe${var:-default}
se expande para o conteúdo da variávelvar
ou, se for não definido ou nulo, a substituição fornecida (neste caso de exemplo,default
; ou no caso de uso real aqui,Did_Not_Resolve
). Você pode encontrar mais detalhes sobre isso nabash
página do manual, na seção chamada "Expansão de Parâmetros".
O resultado final disso é a saída em cada linha, na seguinte ordem, do nome do host, a Tabe o endereço, se houver, ou o texto, Did_Not_Resolve
se não houver.