nslookup awk a un archivo que muestra "respuesta"

nslookup awk a un archivo que muestra "respuesta"

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 >> file3para 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 .. echobucle rápido:

for h in $( cat hosts.list ); do
    a=$(dig +short $h | head -n1)
    echo -e "$h\t${a:-Did_Not_Resolve}"
done

diges una herramienta DNS un poco más amigable con las secuencias de comandos que nslookup, el uso de la +shortopció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 bashexpansió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 diges 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 diges +short, que reduce la salida a la dirección IP del host determinado o, en caso contrario, a una cadena vacía. Ejecuto digen un subshell ( $( dig [...] )) porque estoy capturando su salida y asignola a la variable a(para "dirección"). Estoy canalizando la salida a digtravés head -n1de algunos hosts (como el host unix.stackexchange.comque 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 echodeclaración específicamente:

echo -e "$h\t${a:-Did_Not_Resolve}"
  • El -einterruptor me dice echoque usarémisecuencias de escape. En este caso, estoy usando \twhich, cuando se combina con -e, se convierte en un Tabescape en lugar de un literal t.
  • $hes, como era de esperar, simplemente reemplazado con el contenido de la variable h.
  • \t, como se explicó anteriormente, se convierte en una pestaña.
  • ${a:-Did_Not_Resolve}. Ah, aquí es donde está la magia. bashtiene 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, defaulto en el caso de uso real aquí, Did_Not_Resolve). Puede encontrar más detalles sobre esto en la bashpá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_Resolvesi no la hubiera.

información relacionada