Utilidad de línea de comandos de Linux para resolver nombres de host usando / etc / hosts primero

36

Hay varias utilidades de línea de comandos para resolver nombres de host ( host, dig, nslookup), sin embargo, todos los servidores de nombres de uso exclusivo, mientras que las aplicaciones en aspecto general en /etc/hostsprimer lugar (usando gethostbyname creo).

¿Existe una utilidad de línea de comando para resolver nombres de host que se comporta como una aplicación habitual, buscando /etc/hostsprimero y luego preguntando a un servidor de nombres?

(Soy consciente de que probablemente sería como 3 líneas de c, pero lo necesito dentro de un script de shell algo portátil).

Zulan
fuente
¿Podría explicar su situación un poco más? Ciervas awk '/hostname/ { print $1 }' /etc/hostsayuda?
quanta
@quanta En realidad, la solución actual es grep / sed magic en / etc / hosts. Quería hacerlo más general con una alternativa.
Zulan

Respuestas:

56

Esto se logra fácilmente con getent:

getent hosts 127.0.0.1

getentrealizará búsquedas para cualquier tipo de datos configurados en nsswitch.conf.

womble
fuente
Esta es la herramienta que uso en mis contenedores acoplables Alpine que no tienen otro mecanismo como digo nslookup.
Bruno Bronosky, el
26

Una herramienta que funcionaría es getent. Entonces podrías usar getent hosts www.google.com, o getent hosts localhost. Recuperará entradas de las bases de datos como se especifica en la configuración de su conmutador de servicio de nombres /etc/nsswitch.conf.

Zoredache
fuente
1
Sí, pero eso no recaería en DNS.
slowpoison
No, lo resuelve en el orden nsswitch.conf.
cjc
@slowpoison, eche un vistazo a su configuración nsswitch. Mi sistema tiene files dnspara hosts, lo que significa que / etc / hosts es consultado y luego el solucionador de DNS. Su configuración puede ser diferente.
Zoredache
@cjc, lo hace. No creo que lo haya intentado correctamente.
slowpoison
@ Zoredache, estoy bastante impresionado getent. Gracias por la introducción a este comando.
slowpoison
8

Puede usar un contenedor gethostbyname () (obsoleto) como:

python -c 'import socket;print socket.gethostbyname("www.google.com")'

O un contenedor getaddrinfo () como:

python -c 'import socket;print socket.getaddrinfo("www.google.com","http")[0][4][0]'

Tenga en cuenta que getaddrinfo devolverá todas las instancias como una lista. La última parte del comando selecciona solo la primera tupla. Esto también puede devolver direcciones IPv6.

Mircea Vutcovici
fuente
1
Esto funcionará, pero ha sido obsoleto por un tiempo. Ver linux.die.net/man/3/gethostbyname .
Kyle Smith
Gracias, no lo sabía. ;)
Mircea Vutcovici
Tener un voto a favor. No se ha propuesto ninguna otra línea semi portátil.
user239558
En caso de que esto sea de valor para alguien más, hice una versión de Python 3 con algunas opciones de línea de comandos: github.com/acdha/unix_tools/blob/master/bin/getaddrinfo
Chris Adams
6

resolveip Hará esto.

Curiosamente, es parte de los paquetes mysql-server en RHEL y Ubuntu.

cjc
fuente
6

Puede usar [su idioma favorito aquí] para escribir un script que llame a getnameinfo . Así es como los binarios (como el ping) deberían hacerlo, por lo que está seguro de que recibirá el mismo tratamiento.

Kyle Smith
fuente
6

Uso getent ahosts, por ejemplo:

$ getent ahosts www.google.com | sed -n 's/ *STREAM.*//p'
216.58.210.196
2a00:1450:4006:803::2004

Obtendrá todas las direcciones IPv4 e IPv6, a través del solucionador glibc (por lo tanto, use /etc/hostsprimero, como generalmente se configura en /etc/nsswitch.conf).

No lo use getent hosts, ya que le dará direcciones IPv6 o IPv4 (no ambas), y el protocolo elegido puede no ser uno que no funcione. De hecho, generalmente se prefieren las direcciones IPv6, pero en algunos lugares, los enrutadores filtran (no admiten) los datos IPv6.

vinc17
fuente
3

versión de línea de comando "gethostbyname" :

#!/usr/bin/perl
use Socket;

$host = shift @ARGV;
die("usage: gethostbyname hostname\n") unless(defined($host));

$packed_ip = gethostbyname($host);

if (defined $packed_ip) {
    $ip_address = inet_ntoa($packed_ip);
    print "$ip_address\n";
    exit 0
} else {
    warn "$host not found\n";
    exit 1
}
Erik Aronesty
fuente
2

Podrías ser realmente hacky y usar arp:

arp -n somehostname | tr -d '()' | awk '{print $2}'

pero eso sería realmente feo, así que no deberías hacer eso.

Paul M
fuente
2

getent hostsestá roto. Prefiere direcciones IPv6, gai.confdebe configurarse para preferir ipv4 pero ...

El Perl gethostbynameusa la precedencia en/etc/nsswitch.conf

hosts: files dns

Entonces esto funciona como getent hostsdebería funcionar para mí.

También:

perl -e 'use Socket; print inet_ntoa(inet_aton("www.google.com")) . "\n";'

Deberia trabajar.

Jan Wortelboer
fuente
55
No está roto, simplemente no usa getaddrinfo (que dice /etc/gai.conf). Para usar getaddrinfo, ejecute getent ahosts.
craig65535
1

Prueba esto:

if [ `grep -c "hostname" /etc/hosts` -ge 1 ]; then
    ip=`awk '/hostname/ { print $1 }' /etc/hosts`
else
    ip=`host hostname | awk '/hostname has address/ { print $4 }'`
fi
quanta
fuente
-1

El siguiente comando realizará la búsqueda a través de DNS / etc / hosts a través de la búsqueda directa del servidor DNS.

ping -W2 -c1 google.com | grep PING | sed -r "s/^[^\(]*\(([\.0-9]*)\).*/\1/"

Este comando intentará hacer ping a un dominio (en este caso, google.com) una vez con un tiempo de espera de 2 segundos, obtenga la primera línea del comando PING que indicará "PING google.com (216.58.199.36) 56 (84 ) bytes de datos ", luego use Stream Editor (sed) para detectar el primer conjunto de corchetes y extraer los datos dentro de ellos, que es la dirección IP que estamos buscando.

NOTA: la expresión regex no funcionará si hay paréntesis (también conocidos como corchetes circulares) en la URL, pero este sería un caso raro.

John
fuente