¿Cuál es la forma más concisa de resolver un nombre de host en una dirección IP en un script Bash? Estoy usando Arch Linux .
linux
bash
networking
dns
Eugene Yarmash
fuente
fuente
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
respuesta esté en algún lugar cerca del fondo. Es el más simple, no requiere paquetes adicionales y también es más fácil de analizar desde un script Bash.getent hosts somehost
, al ejecutar esto mientras está encendidosomehost
, producirá una dirección IPv6 , que es diferente de cómo la mayoría de las otras herramientas (ping
,ssh
al menos) resuelven nombres y rompen algunas cosas. Use el enahosts
lugar dehosts
.ahostsv4
) o IPv6 (ahostsv6
) específicamente ? Personalmente, no encuentro nada malo con la solicitud no específica que devuelve IPv6. Su código debe estar preparado. IPv6 ha estado disponible por más de 20 años.hosts
, y hasta ahora 4 personas han votado por el comentario de vinc17 que expresa el dolor causado por "repentinamente IPv6". Estar preparado para IPv6 no siempre es el problema: muchos programas necesitan una forma de determinar si dos nombres / direcciones se refieren al mismo host. Pueden usar una simple coincidencia de cadenas o deben saber mucho sobre la red para encontrar la respuesta "verdadera". Este último es un campo minado, por lo que muchos programas y sistemas de terceros, sobre los que no tengo control, usan el primero.Respuestas:
Puede usar
getent
, lo que viene conglibc
(por lo que casi seguro lo tiene en Linux). Esto se resuelve usando gethostbyaddr / gethostbyname2, y también se verificará/etc/hosts
/ NIS / etc:O, como Heinzi dijo a continuación, puede usarlo
dig
con el+short
argumento (consulta los servidores DNS directamente, no mira/etc/hosts
/ NSS / etc.):Si
dig +short
no está disponible, cualquiera de los siguientes debería funcionar. Todos estos consultan DNS directamente e ignoran otros medios de resolución:Si solo desea imprimir una IP, agregue el
exit
comando alawk
flujo de trabajo.fuente
host www.google.com
,dig +short www.google.com
,host ipv6.google.com
,dig +short ipv6.google.com
,host www.facebook.com
,dig +short www.facebook.com
.host
puede agotar el tiempo de espera y no devuelve nada Para algunos dominios,dig +short
puede devolver el alias de dominio en la primera línea. Por lo tanto, para garantizar que la salida sea una dirección IPv4, usedig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1
.getent hosts <host>
es incorrecto, ya que, por ejemplo, puede proporcionar una dirección IPv6 mientras IPv6 no funciona. La solución correcta es usargetent ahosts <host>
para probar tanto IPv6 como IPv4 si es necesario.Con
host
del paquete dnsutils :(Se corrigió el nombre del paquete de acuerdo con los comentarios. Como nota, hay otras distribuciones
host
en diferentes paquetes: Debian / Ubuntu bind9-host , openSUSE bind-utils , Frugalware bind ).fuente
host
funcionó bien, graciashost
veces devuelve una salida de varias líneas (en el caso de redireccionamientos), querráhost unix.stackexchange.com | tail -n1
si solo desea la línea con la dirección IP.host
es una herramienta DNS (similares anslookup
) por lo que sólo mira hacia arriba anfitriones en el DNS, no en por ejemplo/etc/hosts
. Entonces NO es una respuesta a la pregunta de OP.Tengo una herramienta en mi máquina que parece hacer el trabajo. La página del manual muestra que parece venir con mysql ... Así es como podría usarlo:
El valor de retorno de esta herramienta es diferente de 0 si el nombre de host no se puede resolver:
ACTUALIZACIÓN En fedora, viene con mysql-server:
Supongo que crearía una dependencia extraña para tu script ...
fuente
getent
, como se detalla en la otra respuesta, también analiza / etc / hosts y viene con glibc, por lo que no tiene dependencias en un sistema Linux.El siguiente comando usando le
dig
permite leer el resultado directamente sin ningún sed / awk / etc. magia:dig
También está incluido en eldnsutils
paquete.Nota :
dig
tiene un valor de retorno de0
, incluso si el nombre no se pudo resolver. Por lo tanto, deberá verificar si la salida está vacía en lugar de verificar el valor de retorno:Nota 2 : Si un nombre de host tiene varias direcciones IP (intente
debian.org
, por ejemplo), todas serán devueltas. Este "problema" afecta a todas las herramientas mencionadas en esta pregunta hasta ahora:fuente
fuente
ahosts
,ahostsv4
,ahostsv6
congetent
.cut
no para getent's, que se utilizan\t
para separar columnas. Este es el caso de Solaris.cut
sin-d
(predeterminado\t
como delimitador). En Linux son espacios, por lo tanto, la línea anterior funciona.Las soluciones dadas hasta ahora funcionan principalmente en el caso más simple: el nombre de host se resuelve directamente en una sola dirección IPv4. Este podría ser el único caso en el que necesite resolver nombres de host, pero si no, a continuación se presenta una discusión sobre algunos casos que podría necesitar manejar.
Chris Down y Heinzi discutieron brevemente el caso en el que el nombre de host se resuelve en más de una dirección IP. En este caso (y otros a continuación), las secuencias de comandos básicas bajo el supuesto de que un nombre de host se resuelve directamente en una sola dirección IP pueden romperse. A continuación, un ejemplo con un nombre de host que se resuelve en más de una sola dirección IP:
Pero que es
www.l.google.com
? Aquí es donde debe introducirse el caso de alias . Veamos el siguiente ejemplo:Por
www.google.com
lo tanto , no se resuelve directamente en direcciones IP, sino en un alias que se resuelve en varias direcciones IP. Para obtener más información sobre alias, consulte aquí . Por supuesto, el caso donde un alias tiene una sola dirección IP es posible, como se muestra a continuación:¿Pero se pueden encadenar alias? La respuesta es sí:
No encontré ningún ejemplo en el que un nombre de host se resuelva en un alias que no se resuelva en una dirección IP, pero creo que el caso podría ocurrir.
Más que múltiples direcciones IP y alias, ¿hay otros casos especiales ... ¿qué pasa con IPv6? Tu podrías intentar:
Donde el nombre de host
ipv6.google.com
es un nombre de host solo IPv6. ¿Qué pasa con los nombres de host de doble pila?Nuevamente sobre IPv6, si su host es solo IPv4, aún puede resolver direcciones IPv6 (probado en un WinXP solo IPv4 y con ipv6.google.com, puede probarlo en Linux). En este caso, la resolución tiene éxito, pero un ping falla con un mensaje de error de host desconocido . Este podría ser un caso en el que su script falla.
Espero que esas observaciones hayan sido útiles.
fuente
host
ni siquiera dice "tiene dirección" para mis cajas.Para evitar el problema con los alias y obtener siempre una sola dirección IP lista para usar:
fuente
funciona sin dependencias en otros sistemas (y para hosts especificados en / etc / hosts)
fuente
ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
trabaja para las declaraciones en el interior/etc/hosts
, también ... y es la herramienta de go-to-para todo tipo de bases de datos del sistema (passwd, grupo, alias, servicios).Simple pero útil:
getent ahostsv4 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent ahostsv6 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent hosts google.de | head -n 1 | cut -d ' ' -f 1
Todos los comandos resolverán una dirección IP si el host todavía existe. Si el host apunta a CNAME, también obtendrá la IP en ese caso.
El primer comando devuelve la dirección IPv4 resuelta
El segundo comando devuelve la dirección IPv6 resuelta
El tercer comando devolverá la dirección preferida de los propietarios a la dirección IPv4 o IPv6.
fuente
host
eso requiera la instalación debindutils
Aquí hay una ligera variación del
ping
enfoque que tiene en cuenta "host desconocido" (al canalizar a través de stderr) y utilizatr
para evitar el uso desed
expresiones regulares:En caso de que sea importante capturar el valor de salida, lo siguiente funcionará (aunque menos elegante):
fuente
Para completar la respuesta de Chris Down y abordar los comentarios de jfgagne sobre los alias (posiblemente encadenados), aquí hay una solución que:
/etc/hosts
archivo (en mi caso no lo quería); para consultarlo, la solución python de dbernt es perfecta)no usa awk / sed
Siempre devuelve la primera dirección IP o tring vacío si no se resuelve. con versión de cavar:
fuente
fuente
Me hubiera gustado agregar esto como comentario a Andrew McGregor Re: ping. Sin embargo, no me lo permitió, así que necesito agregar esto como otra respuesta. (Si alguien puede moverlo a un comentario, siéntase libre de hacerlo).
Esta es otra variante, solo usando ping y grep:
grep -E
para expresiones regulares extendidas ygrep -o
para devolver solo la parte coincidente. la expresión regular en sí busca uno o varios dígitos ([0-9]+
) y, opcionalmente, un punto (\.?
) cuatro veces ({4}
)fuente
Podrías usar
host
:fuente
Aquí hay una receta de Bash que preparé usando las respuestas de otras personas: primero intenta
/etc/hosts
, luego recurre a nslookup:fuente
getent hosts
no es solo una búsqueda en / etc / hosts: es una llamada de resolución DNS completa a gethostbyaddr (3) , y es muy poco probable que falle en un caso en el quedig
tenga éxito. Vea la página del manual para getent .getent
sigue siendo mi favorito, aunque también me gustadig +short
fue la solución que encontré sin servidor DNS
fuente
Quizás no sea el más conciso, pero parece ser robusto y eficiente:
Esto generará una sola IP IPv4, así como también regresará
1
en caso de falla, mientras enmascara la salida stderr.Puedes usarlo así:
Si desea una dirección IPv6, simplemente reemplácela
-4
con-6
.fuente
dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'
fuente
1 línea resuelve una lista de nombre de host
fuente
Estoy haciendo esto todo el tiempo en mi Mac que no tiene
getent
.ping
Parece un truco. Me gustaría tener/etc/hosts
en cuenta también.Entonces, escribí un estúpido contenedor para
dns.lookup
ustedes que tienen Node.js instalado para proporcionar una CLI:fuente
cavar es demasiado lento, nslookup es mucho más rápido
fuente
No conozco la forma más fácil para un script bash, pero si desea resolver un nombre de host y ver si el host está activo,
ping
¡ use !Será
ping
el host una vez y resolverá el nombre del host a la dirección IP.fuente
Sí, ya hay muchas respuestas, pero falta una solución con perl:
En un script bash se podría usar así:
Los módulos utilizados aquí son módulos centrales, por lo que deberían estar disponibles en todas partes sin instalar con CPAN.
fuente
perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null
Es mucho más limpio. pero nadie más que nosotros dos estamos usando pörl, todos los demás usan Pascal Script, por supuesto.Can't call method "addr" on an undefined value
no es exactamente el mejor mensaje de error, pero puede dar una pista sobre el problema.fuente
print
debería usarse en lugar dep
.Este comando mostrará la dirección IP (reslove el dominio a IP)
fuente
Además de la solución anterior, puede traducir varios nombres de host a ip a través del script a continuación, la única dependencia es el comando "ping" en el núcleo de Unix:
fuente