
Actualmente estoy ejecutando un script que usa nslookup en varios hosts y luego usa awk para imprimir las líneas deseadas en una tabla. Estoy imprimiendo una línea en el archivo 1 y otra en el archivo 2, y luego la uso paste file1 file2 >> file3
para producir esta tabla.
La mesa se ve así
Host IP
name 10.10.10.10
name 10.10.10.10
name 10.10.10.10
En su mayor parte, esto está funcionando. Pero por alguna razón, alrededor de 20 de mis 160 resultados obtienen "respuesta:" en la columna de la izquierda y el nombre de host aparece en la derecha. Como esto:
Host IP
answer: hostname
Esto aparece aleatoriamente en todos los resultados y no puedo entenderlo porque nslookup no tiene la palabra "respuesta:" en ninguna parte para que el script se active accidentalmente.
Aquí está mi guión como referencia:
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
Respuesta1
Si su objetivo deseado es simplemente crear una tabla de nombres de host y direcciones IP, y no le importa especialmente usar nslookup
, aparentemente pude crear el resultado deseado con un for .. echo
bucle 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
es una herramienta DNS un poco más amigable con las secuencias de comandos que nslookup
, el uso de la +short
opción hace que la salida sea aún más limpia. La salida de una solicitud para la cual no hay registro es una cadena vacía, por lo que uso la bash
expansión de parámetro predeterminado incorporada ( ${var:-default}
) para manejar el caso de que no haya registro dando una respuesta "predeterminada" 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
El rendimiento final es 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
Una alternativa a dig
es también 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
En respuesta a las preguntas en el comentario a continuación:
La única opción que uso dig
es +short
, que reduce la salida a la dirección IP del host determinado o, en caso contrario, a una cadena vacía. Ejecuto dig
en un subshell ( $( dig [...] )
) porque estoy capturando su salida y asignola a la variable a
(para "dirección"). Estoy canalizando la salida a dig
través head -n1
de algunos hosts (como el host unix.stackexchange.com
que devuelve múltiples direcciones IP; en aras de la simplicidad, simplemente tomo la primera.
La razón por la que esto se incluye en una variable es para que podamos usar un truco simple de expansión de parámetros para proporcionar el texto "No se resolvió" en lugar de una cadena vacía, como se describió anteriormente en este documento.
Ampliando lo solicitado en la echo
declaración específicamente:
echo -e "$h\t${a:-Did_Not_Resolve}"
- El
-e
interruptor me diceecho
que usarémisecuencias de escape. En este caso, estoy usando\t
which, cuando se combina con-e
, se convierte en un Tabescape en lugar de un literalt
. $h
es, como era de esperar, simplemente reemplazado con el contenido de la variableh
.\t
, como se explicó anteriormente, se convierte en una pestaña.${a:-Did_Not_Resolve}
. Ah, aquí es donde está la magia.bash
tiene la capacidad, al realizar la expansión de parámetros, de hacer un poco de introspección como parte del proceso. La sintaxis${var:-default}
se expande al contenido de la variable.var
o, si no está configurado o es nulo, el reemplazo proporcionado (en este caso de ejemplo,default
o en el caso de uso real aquí,Did_Not_Resolve
). Puede encontrar más detalles sobre esto en labash
página del manual, en la sección denominada "Expansión de parámetros".
El resultado final de esto es generar en cada línea, en el siguiente orden, el nombre de host, a Taby la dirección si la hubiera, o el texto Did_Not_Resolve
si no la hubiera.