Was ist die präziseste Methode, um einen Hostnamen in einem Bash-Skript in eine IP-Adresse aufzulösen? Ich benutze Arch Linux .
linux
bash
networking
dns
Eugene Yarmash
quelle
quelle
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
Antwort irgendwo unten in der Nähe des Bodens ist. Es ist das einfachste, erfordert keine zusätzlichen Pakete und ist auch einfacher aus einem Bash-Skript zu analysieren.getent hosts somehost
, wenn diese ausgeführt wird, während aufsomehost
wird eine IPv6 - Adresse erzeugen , die aus verschiedenen ist , wie die meisten anderen Werkzeuge (ping
,ssh
zumindest) Namen aufzulösen, und einige Dinge bricht. Verwenden Sieahosts
statthosts
.ahostsv4
) oder IPv6- (ahostsv6
) Adressen anzufordern ? Persönlich finde ich nichts Falsches an der unspezifischen Anforderung, IPv6 zurückzugeben. Ihr Code sollte vorbereitet sein. IPv6 gibt es seit mehr als 20 Jahren.hosts
, und bisher haben 4 Personen den Kommentar von vinc17, in dem der durch "Plötzlich IPv6" verursachte Schmerz zum Ausdruck gebracht wird, positiv bewertet. Die Vorbereitung auf IPv6 ist nicht immer das Problem: Viele Programme müssen feststellen, ob sich zwei Namen / Adressen auf denselben Host beziehen. Sie können entweder einen einfachen String-Abgleich verwenden, oder sie müssen viel über das Netzwerk wissen, um die "wahre" Antwort zu finden. Letzteres ist ein Minenfeld, und so viele Programme und Systeme von Drittanbietern - über die ich keine Kontrolle habe - verwenden das erstere.Antworten:
Sie können verwenden
getent
, was mit kommtglibc
(so haben Sie es mit ziemlicher Sicherheit unter Linux). Dies löst die Verwendung von gethostbyaddr / gethostbyname2 auf und überprüft daher auch/etc/hosts
/ NIS / etc:Oder, wie Heinzi weiter unten sagte, können Sie
dig
das+short
Argument verwenden (DNS-Server werden direkt/etc/hosts
abgefragt, / NSS / etc wird nicht angezeigt):Wenn
dig +short
nicht verfügbar, sollte eine der folgenden Möglichkeiten funktionieren. Alle diese fragen DNS direkt ab und ignorieren andere Lösungsmöglichkeiten:Wenn Sie nur eine IP drucken möchten, fügen Sie den
exit
Befehl zumawk
Workflow hinzu.quelle
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
kann eine Zeitüberschreitung auftreten und es wird nichts zurückgegeben. Bei einigen Domänen wirddig +short
möglicherweise ein Domänenalias in der ersten Zeile zurückgegeben. Verwenden Sie also, um sicherzustellen, dass die Ausgabe eine IPv4-Adresse istdig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1
.getent hosts <host>
ist falsch, da beispielsweise eine IPv6-Adresse vergeben werden kann, während IPv6 nicht funktioniert. Die richtige Lösung besteht darin, bei Bedarfgetent ahosts <host>
sowohl IPv6 als auch IPv4 zu testen.Mit
host
aus dem dnsutils- Paket:(Der Name des Pakets wurde gemäß den Kommentaren korrigiert . Als Hinweis haben andere Distributionen
host
in verschiedenen Paketen: Debian / Ubuntu bind9-host , openSUSE bind-utils , Frugalware bind .)quelle
host
funktioniert, dankehost
manchmal mehrzeilige Ausgaben zurückgegeben werden (im Fall von Weiterleitungen),host unix.stackexchange.com | tail -n1
wenn Sie nur die Zeile mit der IP-Adresse benötigen.host
ist ein (ähnlichesnslookup
) DNS-Tool , mit dem nur Hosts im DNS gesucht werden, nicht z/etc/hosts
. Es ist also KEINE Antwort auf die Frage von OP.Ich habe ein Werkzeug auf meiner Maschine, das den Job zu erledigen scheint. Die Manpage zeigt, dass es mit MySQL zu kommen scheint ... Hier ist, wie Sie es verwenden könnten:
Der Rückgabewert dieses Tools unterscheidet sich von 0, wenn der Hostname nicht aufgelöst werden kann:
UPDATE Auf Fedora kommt es mit MySQL-Server:
Ich denke, es würde eine seltsame Abhängigkeit für Ihr Skript schaffen ...
quelle
getent
Wie in der anderen Antwort ausführlich beschrieben, wird auch / etc / hosts betrachtet und mit glibc geliefert, sodass keine Abhängigkeiten von einem Linux-System bestehen.Mit dem folgenden Befehl
dig
können Sie das Ergebnis direkt ohne sed / awk / etc lesen. Magie:dig
ist ebenfalls imdnsutils
Paket enthalten.Hinweis :
dig
hat einen Rückgabewert von0
, auch wenn der Name nicht aufgelöst werden konnte. Sie müssen also überprüfen, ob die Ausgabe leer ist, anstatt den Rückgabewert zu überprüfen:Hinweis 2 : Wenn ein Hostname mehrere IP-Adressen hat (versuchen Sie es
debian.org
zum Beispiel), werden alle zurückgegeben. Dieses "Problem" betrifft alle Tools, die bisher in dieser Frage erwähnt wurden:quelle
quelle
ahosts
auchahostsv4
,ahostsv6
mitgetent
.cut
Wird nicht für getent's verwendet\t
, um Spalten zu trennen. Dies ist unter Solaris der Fall.cut
ohne ausführen-d
(standardmäßig\t
als Begrenzer). Unter Linux sind es Leerzeichen, daher funktioniert die obige Zeile.Die bisher angegebenen Lösungen funktionieren meist im einfacheren Fall: Der Hostname wird direkt in eine einzelne IPv4-Adresse aufgelöst. Dies ist möglicherweise der einzige Fall, in dem Sie Hostnamen auflösen müssen. Wenn dies nicht der Fall ist, finden Sie im Folgenden eine Erläuterung einiger Fälle, die Sie möglicherweise behandeln müssen.
Chris Down und Heinzi diskutierten kurz den Fall, in dem der Hostname in mehr als eine IP-Adresse aufgelöst wird. In diesem Fall (und in den folgenden Fällen) kann die grundlegende Skripterstellung unter der Annahme, dass ein Hostname direkt in eine einzelne IP-Adresse aufgelöst wird, zum Erliegen kommen. Unten ein Beispiel mit einem Hostnamen, der in mehr als eine einzelne IP-Adresse aufgelöst wird:
Aber was ist
www.l.google.com
? Hier muss der Alias eingeführt werden. Schauen wir uns das folgende Beispiel an:Wird
www.google.com
also nicht direkt in IP-Adressen aufgelöst, sondern in einen Alias, der sich in mehrere IP-Adressen auflöst. Weitere Informationen zu Aliasnamen finden Sie hier . Natürlich ist der Fall möglich, in dem ein Alias eine einzelne IP-Adresse hat, wie unten gezeigt:Aber können Aliase angekettet werden? Die Antwort ist ja:
Ich habe kein Beispiel gefunden, bei dem ein Hostname in einen Aliasnamen aufgelöst wird, der nicht in eine IP-Adresse aufgelöst wird, aber ich denke, der Fall könnte eintreten.
Gibt es neben mehreren IP-Adressen und Aliasnamen noch einige andere Sonderfälle? Was ist mit IPv6? Du könntest es versuchen:
Wobei der Hostname
ipv6.google.com
ein IPv6-Hostname ist. Was ist mit Dual-Stack-Hostnamen:Auch bei IPv6 können Sie IPv6-Adressen auflösen, wenn Ihr Host nur IPv4 ist (getestet unter WinXP nur IPv4 und mit ipv6.google.com können Sie es unter Linux versuchen). In diesem Fall ist die Auflösung erfolgreich, aber ein Ping schlägt mit einer unbekannten Hostfehlermeldung fehl . Dies kann ein Fall sein, in dem Ihre Skripterstellung fehlschlägt.
Ich hoffe, diese Bemerkungen waren nützlich.
quelle
host
gibt nicht einmal "hat Adresse" für meine Boxen an.So vermeiden Sie das Problem mit Aliasnamen und halten immer eine einzelne IP-Adresse bereit:
quelle
funktioniert ohne Abhängigkeiten von anderen Systemen (und für Hosts, die in / etc / hosts angegeben sind)
quelle
ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
Funktioniert auch für Deklarationen im Inneren/etc/hosts
... und ist das Go-to-Tool für alle Arten von Systemdatenbanken (passwd, group, aliases, services).Einfach aber nützlich:
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
Alle Befehle lösen eine IP-Adresse auf, wenn der Host noch vorhanden ist. Wenn der Host auf CNAME zeigt, erhält er in diesem Fall auch die IP.
Der erste Befehl gibt die aufgelöste IPv4-Adresse zurück
Der zweite Befehl gibt die aufgelöste IPv6-Adresse zurück
Der dritte Befehl gibt die bevorzugte IPv4- oder IPv6-Adresse des Besitzers zurück.
quelle
host
erfordern die Installation derbindutils
Hier ist eine kleine Variation des
ping
Ansatzes, der "unbekannten Host" berücksichtigt (durch Weiterleiten durch stderr) und verwendettr
, um die Verwendung vonsed
regulären Ausdrücken zu vermeiden :Wenn es wichtig ist, den Exit-Wert zu erfassen, funktioniert Folgendes (wenn auch weniger elegant):
quelle
Um die Antwort von Chris Down zu vervollständigen und jfgagne-Kommentare zu (möglicherweise verketteten) Aliasen zu adressieren, gibt es folgende Lösung:
/etc/hosts
Datei ab (in meinem Fall wollte ich es nicht); um es abzufragen, ist die Python-Lösung von dbernt perfekt)benutzt awk / sed nicht
Gibt immer die erste IP-Adresse oder einen leeren String zurück, wenn dieser nicht aufgelöst wird. mit Version von dig:
quelle
quelle
Ich hätte dies gerne als Kommentar zu Andrew McGregor Re: ping hinzugefügt. Allerdings ließ es mich nicht, also muss ich dies als eine andere Antwort hinzufügen. (Wenn jemand es in einen Kommentar verschieben kann, zögern Sie nicht.)
Dies ist eine andere Variante, die nur ping und grep verwendet:
grep -E
für erweiterte reguläre Ausdrücke undgrep -o
um nur den passenden Teil zurückzugeben. Der reguläre Ausdruck sucht nach einer oder mehreren Ziffern ([0-9]+
) und optional nach einem Punkt (\.?
) viermal ({4}
).quelle
Sie könnten verwenden
host
:quelle
Hier ist ein Bash-Rezept, das ich mir mit den Antworten anderer Leute ausgedacht habe - zuerst versucht
/etc/hosts
, dann greift ich auf nslookup zurück:quelle
getent hosts
handelt sich nicht nur um eine Suche in / etc / hosts - es handelt sich um einen vollständigen DNS-auflösenden Aufruf von gethostbyaddr (3) , und es ist sehr unwahrscheinlich, dass er fehlschlägt, wenn diesdig
gelingt. Siehe die Manpage für getent .getent
bleibt mein Favorit, obwohl ich auch magdig +short
war die Lösung, die ich ohne DNS-Server gefunden habe
quelle
Vielleicht nicht die prägnanteste, aber sie scheint robust und effizient zu sein:
Dies gibt eine einzelne IPv4-IP aus und kehrt
1
im Fehlerfall zurück, während die stderr-Ausgabe maskiert wird.Du kannst es so benutzen:
Wenn Sie stattdessen eine IPv6-Adresse wünschen, ersetzen Sie diese
-4
durch-6
.quelle
dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'
quelle
1 Zeile löst eine Liste von Hostnamen auf
quelle
Ich mache das die ganze Zeit auf meinem Mac, der nicht hat
getent
.ping
scheint wie ein Hack. Das möchte ich auch/etc/hosts
berücksichtigen.Deshalb habe ich einen dummen Wrapper für
dns.lookup
Sie geschrieben, auf dem Node.js installiert ist, um eine CLI bereitzustellen:quelle
dig ist zu langsam, nslookup ist viel schneller
quelle
Ich kenne den einfachsten Weg für ein Bash-Skript nicht, aber wenn Sie einen Hostnamen auflösen und sehen möchten, ob der Host aktiv ist, verwenden Sie
ping
!Wird
ping
der Host einmal und den Hostnamen in IP-Adresse auflösen.quelle
Ja, es gibt bereits viele Antworten, aber eine Lösung mit Perl fehlt:
In einem Bash-Skript könnte dies so aussehen:
Die hier verwendeten Module sind Kernmodule und sollten daher überall verfügbar sein, ohne mit CPAN installiert zu werden.
quelle
perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null
ist viel sauberer. aber niemand außer uns beiden benutzt pörl, alle anderen benutzen natürlich Pascal Script.Can't call method "addr" on an undefined value
ist nicht gerade die beste Fehlermeldung, kann aber einen Hinweis auf das Problem geben.quelle
print
sollte wahrscheinlich anstelle von verwendet werdenp
.Dieser Befehl zeigt die IP-Adresse an (Domain wird auf IP umgestellt)
quelle
Neben der obigen Lösung können Sie mehrere Hostnamen über das folgende Skript in ip übersetzen. Die einzige Abhängigkeit ist der Befehl "ping" in Core-Unix:
quelle