Frage Linux-Befehlszeilendienstprogramm, um Hostnamen zuerst mit / etc / hosts aufzulösen


Es gibt mehrere Befehlszeilenprogramme zum Auflösen von Hostnamen (host, dig, nslookup), jedoch verwenden sie alle ausschließlich Nameserver, während Anwendungen im Allgemeinen nachsehen /etc/hosts zuerst (mit gethostbyname glaube ich).

Gibt es ein Befehlszeilendienstprogramm, um Hostnamen aufzulösen, die sich wie eine normale Anwendung verhalten und so hineinschauen /etc/hosts zuerst und nur dann einen Nameserver fragen?

(Ich bin mir bewusst, dass es wahrscheinlich wie 3 Zeilen von c wäre, aber ich brauche es in einem etwas tragbaren Shell-Skript.)


30
2017-08-22 10:49


Ursprung


Könntest du bitte etwas mehr deine Situation erklären? Tut awk '/hostname/ { print $1 }' /etc/hosts Hilfe? - quanta
@quanta Eigentlich ist die aktuelle Lösung grep / sed magic auf / etc / hosts. Ich wollte das mit einem Fallback allgemeiner machen. - Zulan


Antworten:


Dies wird leicht mit erreicht getent:

getent hosts 127.0.0.1

getent Sucht nach allen Arten von Daten, die konfiguriert sind nsswitch.conf.


49
2017-08-22 11:06



Dies ist das Werkzeug, das ich in meinen alpinen Docker-Containern verwende, die keinen anderen Mechanismus haben dig oder nslookup. - Bruno Bronosky


Ein Werkzeug, das funktionieren würde, ist getent. So könnten Sie verwenden getent hosts www.google.com, oder getent hosts localhost. Es ruft Einträge aus den Datenbanken ab, die in Ihrer Name Service Switch-Konfiguration angegeben sind /etc/nsswitch.conf.


24
2018-03-19 19:53



Ja, aber das würde nicht auf DNS zurückgreifen. - slowpoison
Nein, es wird in der Reihenfolge nsswitch.conf aufgelöst. - cjc
@slowpoison, Schau dir deine nsswitch config an. Mein System hat files dns für Hosts, was bedeutet, dass / etc / hosts konsultiert wird und dann der DNS-Resolver. Ihre Konfiguration kann anders sein. - Zoredache
@cjc, tut es. Ich glaube nicht, dass ich es richtig ausprobiert habe. - slowpoison
@Zoredache, ich bin ziemlich beeindruckt von getent. Danke für die Einleitung zu diesem Befehl. - slowpoison


resolveip werde das tun.

Seltsamerweise ist es Teil der MySQL-Server-Pakete auf RHEL und Ubuntu.


5
2018-03-19 19:53





Sie könnten [Ihre Lieblingssprache hier] verwenden, um ein Skript zu schreiben, das anruft getnameinfo. Das sollten Binärdateien (wie Ping) sein, damit Sie sicher sind, dass Sie die gleiche Behandlung erhalten.


5
2018-03-19 20:06





Sie können einen gethostbyname () (veraltet) Wrapper verwenden wie:

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

Oder ein getaddrinfo () Wrapper wie:

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

Beachten Sie, dass getaddrinfo alle Instanzen als Liste zurückgibt. Der letzte Teil des Befehls wählt nur das erste Tupel aus. Dies kann auch IPv6-Adressen zurückgeben.


5
2018-03-19 20:06



Das wird funktionieren, aber es ist für eine Weile obsolet. Sehen linux.die.net/man/3/gethostbyname. - Kyle Smith
Danke, ich wusste es nicht. ;) - Mircea Vutcovici
Habe eine Verbesserung. Kein anderer halb-portabler Einzeiler wurde vorgeschlagen. - user239558
Falls dies für irgendjemand anderen von Wert ist, habe ich eine Python 3-Version mit ein paar Befehlszeilenoptionen erstellt: github.com/acdha/unix_tools/blob/master/bin/getaddrinfo - Chris Adams


Benutzen getent ahosts, zum Beispiel:

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

Sie erhalten alle IPv4 - und IPv6 - Adressen über den glibc - Resolver (also mit /etc/hosts zuerst, wie normalerweise konfiguriert in /etc/nsswitch.conf).

Verwende nicht getent hosts, da es entweder IPv6- oder IPv4-Adressen (nicht beides) gibt, und das gewählte Protokoll möglicherweise nicht eines ist, das nicht funktioniert. Tatsächlich werden IPv6-Adressen im Allgemeinen bevorzugt, aber an einigen Stellen werden IPv6-Daten von den Routern gefiltert (nicht unterstützt).


4
2017-10-03 15:17





"gethostbyname" Befehlszeilenversion:

#!/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
}

1
2018-04-22 17:43





Du könntest wirklich hacky sein und benutzen arp:

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

aber das wäre wirklich hässlich, also solltest du das nicht tun.


1
2018-06-28 16:23





getent hosts ist kaputt. Es bevorzugt IPv6-Adressen, gai.conf sollte konfiguriert sein, um ipv4 aber zu bevorzugen ....

Die Perl gethostbyname verwendet die Priorität in /etc/nsswitch.conf

hosts: files dns

So funktioniert das getent hosts sollte für mich arbeiten.

Ebenfalls:

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

sollte arbeiten.


1
2017-09-24 06:16



Es ist nicht kaputt, es verwendet nur getaddrinfo nicht (das /etc/gai.conf liest). Um getaddrinfo zu verwenden, führen Sie getent ahosts. - craig65535