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).


¿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.


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.


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.


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.


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.


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.


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
}

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.


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.


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

-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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.