Utilità della riga di comando di Linux per risolvere i nomi host utilizzando prima / etc / hosts


36

Ci sono diverse utility a riga di comando per risolvere i nomi degli host ( host, dig, nslookup), tuttavia essi tutti i server dei nomi di uso esclusivo, mentre le applicazioni in look generale a /etc/hostsprima (utilizzando gethostbyname credo).

Esiste un'utilità da riga di comando per risolvere i nomi host che si comportano come una normale applicazione, cercando in /etc/hostsprimo luogo e solo successivamente chiedendo a un nameserver?

(Sono consapevole che probabilmente sarebbe come 3 righe di c, ma ne ho bisogno all'interno di uno script di shell in qualche modo portatile.)


Potresti spiegare un po 'di più la tua situazione? Does awk '/hostname/ { print $1 }' /etc/hostsaiuto?
quanti,

@quanta In realtà la soluzione attuale è grep / sed magic su / etc / hosts. Volevo renderlo più generale con un fallback.
Zulan,

Risposte:


56

Ciò si ottiene facilmente con getent:

getent hosts 127.0.0.1

getenteseguirà ricerche per qualsiasi tipo di dati configurato in nsswitch.conf.


Questo è lo strumento che uso nei miei container docker Alpine che non hanno altri meccanismi simili digo nslookup.
Bruno Bronosky,

26

Uno strumento che funzionerebbe è getent. Quindi potresti usare getent hosts www.google.com, o getent hosts localhost. Recupererà le voci dai database come specificato nella configurazione dello switch del nome del servizio /etc/nsswitch.conf.


1
Sì, ma ciò non ricadrebbe sul DNS.
slowpoison,

No, lo risolve nell'ordine nsswitch.conf.
cjc

@slowpoison, dai un'occhiata alla tua configurazione di nsswitch. Il mio sistema ha files dnsper gli host, il che significa che / etc / hosts viene consultato e quindi il risolutore DNS. La tua configurazione potrebbe essere diversa.
Zoredache,

@cjc, lo fa. Non credo di averlo provato correttamente.
slowpoison,

@Zoredache, sono abbastanza impressionato getent. Grazie per l'introduzione a questo comando.
slowpoison,

8

È possibile utilizzare un wrapper gethostbyname () (obsoleto) come:

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

O un wrapper getaddrinfo () come:

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

Nota che getaddrinfo restituirà tutte le istanze come un elenco. L'ultima parte del comando seleziona solo la prima tupla. Questo può anche restituire indirizzi IPv6.


1
Funzionerà, ma è stato obsoleto per un po '. Vedi linux.die.net/man/3/gethostbyname .
Kyle Smith,

Grazie, non lo sapevo. ;)
Mircea Vutcovici,

Avere un voto. Non è stato proposto nessun altro rivestimento semi-portatile.
user239558,

Nel caso questo abbia valore per chiunque altro, ho realizzato una versione di Python 3 con alcune opzioni da riga di comando: github.com/acdha/unix_tools/blob/master/bin/getaddrinfo
Chris Adams,

6

resolveip farà questo.

Stranamente, fa parte dei pacchetti mysql-server su RHEL e Ubuntu.


6

Puoi usare [la tua lingua preferita qui] per scrivere uno script che chiama getnameinfo . Ecco come dovrebbero farlo i binari (come il ping), quindi sei sicuro di ricevere lo stesso trattamento.


6

Utilizzare getent ahosts, ad esempio:

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

Otterrai tutti gli indirizzi IPv4 e IPv6, tramite il risolutore glibc (quindi usando /etc/hostsprima, come di solito configurato in /etc/nsswitch.conf).

Non utilizzare getent hosts, poiché fornirà indirizzi IPv6 o IPv4 (non entrambi) e il protocollo scelto potrebbe non essere uno che non funziona. In effetti, gli indirizzi IPv6 sono generalmente preferiti, ma in alcuni punti i dati IPv6 vengono filtrati (non supportati) dai router.


3

Versione della riga di 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

Potresti essere davvero confuso e usare arp:

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

ma sarebbe davvero brutto, quindi non dovresti farlo.


2

getent hostsè rotto. Preferisce gli indirizzi IPv6, gai.confdovrebbe essere configurato per preferire ipv4 ma ....

Il Perl gethostbynameusa la precedenza in/etc/nsswitch.conf

hosts: files dns

Quindi funziona come getent hostsdovrebbe funzionare per me.

Anche:

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

dovrebbe funzionare.


5
Non è rotto, semplicemente non usa getaddrinfo (che legge /etc/gai.conf). Per utilizzare getaddrinfo, eseguire getent ahosts.
craig65535,

1

Prova questo:

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

Il comando seguente eseguirà la ricerca tramite DNS / etc / hosts tramite la ricerca diretta del server DNS.

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

Questo comando tenterà di eseguire il ping di un dominio (in questo caso, google.com) una volta con un timeout di attesa di 2 secondi, ottenere la prima riga del comando PING che indicherà "PING google.com (216.58.199.36) 56 (84 ) byte di dati ", quindi utilizza Stream Editor (sed) per rilevare la prima serie di parentesi ed estrarre i dati al suo interno che è l'indirizzo IP che stiamo cercando.

NOTA: l'espressione regex non funzionerà se ci sono parentesi (aka parentesi circolari) nell'URL, ma questo sarebbe un caso raro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.