Wie kann ich meine eigene IP-Adresse erhalten und in einer Variablen in einem Shell-Skript speichern?
networking
shell-script
ip
Tom Brito
quelle
quelle
Antworten:
Es ist nicht so einfach, wenn Sie WLAN und andere alternative Schnittstellen berücksichtigen möchten. Wenn Sie wissen, für welche Schnittstelle Sie die Adresse möchten (z. B. eth0, die erste Ethernet-Karte), können Sie Folgendes verwenden:
Mit anderen Worten, holen Sie sich die Netzwerkkonfigurationsinformationen, suchen Sie nach
eth0
, holen Sie sich diese und die nächste Zeile (-A 1
), holen Sie sich nur die letzte Zeile, holen Sie sich den zweiten Teil dieser Zeile, wenn Sie mit teilen:
, und holen Sie sich dann den ersten Teil davon, wenn Sie teilen mit platz.quelle
grep
habe Ihrem Code einen Zusatz hinzugefügt , um jede Schnittstelle mit "eth0:" zu ignorieren. dies funktioniert nun wie erwartet (nur die IP-Adresse "eth0" und keine untergeordneten Schnittstellen (eth0: 0, eth0: 1 usw.)ip="$(ifconfig | grep -v 'eth0:' | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
ifconfig eth0
ip address
Ich glaube, die "moderne Methode", um Ihre IPv4-Adresse zu ermitteln, besteht darin, "ip" und nicht "ifconfig" zu analysieren.
oder etwas ähnliches.
quelle
ip
ist für alle von mir verwendeten Red Hat- und Fedora-Distributionen verfügbar.ip
ist Teil des iproute2-Pakets ( linuxfoundation.org/collaborate/workgroups/networking/iproute2 ).ifconfig
undroute
sind angeblich veraltet, obwohl sie weiterhin von vielen Menschen verwendet werden, insbesondere in Skripten.ip
ist nach meiner Meinung viel einfacher zu analysieren.ip
ist auch auf allen Debian- und Debian-basierten Distributionen verfügbar, die ich gesehen habe. Es ist Teil des iproute-Pakets, das als wichtig markiert ist.ip
ist Teil des iproute2-Pakets, das standardmäßig so manche Distribution enthält. Es ist in den meisten guten Repos zu. en.wikipedia.org/wiki/Iproute2/sbin/ip
stattip
?awk
undcut
ist für mich leicht amüsant. Hier ist eine mögliche Alternative, die eigentlich nicht besser sein könnte:ip -o -4 addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'
Warum nicht einfach machen
IP=$(hostname -I)
?quelle
hostname -i
gibt mir nur127.0.0.1
,hostname -I
gibt mir die richtige IP-Adresse ...-i Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses
/etc/hosts
zusammen mit der entsprechenden IP-Adresse hinzuzufügen-I
auf FreeBSD, aber Sie könnendig +short `hostname -f`
Wenn Sie die Adresse einer Schnittstelle benötigen, ist die Installation von moreutils am einfachsten.
ifdata
beantwortet so ziemlich jede Frage, für die Sie versucht wären, dieifconfig
Ausgabe zu analysieren .Wenn Sie Ihre IP-Adresse so herausfinden möchten, wie es von außen gesehen wird (jenseits von NAT usw.), gibt es eine Vielzahl von Diensten, die dies tun. Eines ist ziemlich einfach:
quelle
ifdata
hinzugefügt zu habeniproute2
. Vielleicht eine neue Binärdatei namensipdata
Versuchen Sie Folgendes, um IPv4- und IPv6-Adressen abzurufen und nicht davon auszugehen, dass dies die Hauptschnittstelle ist
eth0
(heutzutageem1
üblicher ):-o
verwendet das einzeilige Ausgabeformat, das einfacher zu verarbeitenread
istgrep
, usw.up
Ausgeschlossen sind Geräte, die nicht aktiv sindscope global
Ausgeschlossen sind private / lokale Adressen wie127.0.0.1
undfe80::/64
primary
schließt temporäre Adressen aus (vorausgesetzt, Sie möchten eine Adresse, die sich nicht ändert)quelle
-4
/-6
filtern. Sie können auch problemlos andere Schnittstellenparameter abrufen. Persönlich mag ich while loop nicht und ich bevorzugegrep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
Kommt darauf an, was du mit eigener IP-Adresse meinst. Systeme haben IP-Adressen in mehreren Subnetzen (manchmal auch mehrere pro Subnetz), von denen einige IPv4- und einige IPv6-Geräte wie Ethernet-Adapter, Loopback-Schnittstellen, VPN-Tunnel, Bridges, virtuelle Schnittstellen usw. verwenden.
Wenn Sie die IP-Adresse meinen, über die ein anderes bestimmtes Gerät Ihren Computer erreichen kann, müssen Sie herausfinden, um welches Subnetz es sich handelt und um welche IP-Version es sich handelt. Bedenken Sie außerdem, dass die IP-Adresse einer Schnittstelle aufgrund von NAT, das von einer Firewall / einem Router ausgeführt wird, möglicherweise nicht mit der IP-Adresse eines Remotehosts übereinstimmt, von dem eine eingehende Verbindung von Ihrem Computer stammt.
Wenn es ein ausgefallenes Quell-Routing oder ein Protokoll- / Port-Routing gibt, kann es schwierig sein, herauszufinden, welche Schnittstelle für die Kommunikation mit einem Remotecomputer über ein bestimmtes Protokoll verwendet wird, und selbst dann gibt es keine Garantie dafür, dass die IP-Adresse dieser Schnittstelle lautet direkt von dem Remote-Computer ansprechbar, der eine neue Verbindung zu Ihrem Computer herstellen möchte.
Für IPv4 (funktioniert wahrscheinlich auch für IPv6) besteht ein Trick, der in vielen Unices, einschließlich Linux, zum Ermitteln der IP-Adresse der Schnittstelle, die zum Erreichen eines bestimmten Hosts verwendet wird, darin, eine Verbindung (2) an einem UDP-Socket zu verwenden und getsockname zu verwenden ():
Zum Beispiel auf meinem Heimcomputer:
Würde verwendet, um die IP-Adresse der Schnittstelle herauszufinden, über die ich 8.8.8.8 erreichen würde (googles DNS-Server). Es würde so etwas wie "192.168.1.123" zurückgeben, was die Adresse der Schnittstelle für die Standardroute zum Internet ist. Google würde jedoch nicht sehen, dass eine DNS-Anfrage von meinem Computer von dieser privaten IP-Adresse stammt, da NAT von meinem Breitband-Router zu Hause ausgeführt wird.
connect () auf einem UDP-Socket sendet kein Paket (UDP ist verbindungslos), bereitet jedoch den Socket durch Abfragen der Routingtabelle vor.
quelle
quelle
-I
anstelle-i
ist besser, da Sie Loopback-Adressen ignorieren möchten. Der endgültige Befehlipa=$(hostname -I|cut -f1 -d ' ')
grep
es nicht ausreicht, leiten Sie es nicht an etwas anderes weiter. Verwenden Sie einfach die etwas anderes (sed
,awk
usw.).Ich will kein Idiot sein, aber es gibt wirklich einen richtigen Weg und das ist es. Sie kürzen die Ausgabe von
ip route
, um nur die Quell-IP zu erhalten. Abhängig davon, welche IP-Adresse Sie erreichen möchten, unterscheiden sich "meine eigene IP-Adresse" (die Worte von OP). Wenn Sie das öffentliche Internet erreichen möchten, ist die Verwendung des DNS-Servers 8.8.8.8 von Google Standard. Damit...Die kurze Antwort lautet:
Hier ist die detaillierte Erklärung
Wenn ich möchte, dass die von mir verwendete IP-Adresse das Internet erreicht , verwende ich Folgendes:
Wenn ich möchte, dass die IP, die ich verwende, etwas in meinem VPN erreicht , verwende ich Folgendes:
Wenn ich möchte, dass die von mir verwendete IP-Adresse mich selbst erreicht , würde ich Folgendes verwenden:
Mehr zu diesem
sed
BefehlLassen Sie mich zunächst sagen, dass Sie bei der Auswahl von Unix-Tools versuchen, die Tools auszuwählen, die die wenigsten Pipes erfordern. Während also einige Antworten
ifconfig
zugrep
zused
leitenhead
sind, ist dies selten nötig. Wenn Sie es sehen, sollte es eine rote Fahne auslösen, die Sie von jemandem mit wenig Erfahrung beraten. Das macht die "Lösung" nicht falsch. Aber es könnte wahrscheinlich eine Straffung gebrauchen.Ich habe gewählt,
sed
weil es knapper ist als der gleiche Workflow inawk
. (Ich habe da ein awk-Beispiel unten.) Ich denke kein anderes Tool als diese 2 wäre angemessen.Lassen Sie uns untersuchen, was
Hinweis:sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
macht:Früher habe ich verwendet,
sed -n '/src/{s/.*src *//p;q}'
aber ein Kommentator hat darauf hingewiesen, dass einige Systeme nach demsrc
Feld nachgestellte Daten haben .Awk benutzen
Mehr über mein Netzwerk
Meine
ifconfig
Shows, die ichtun0
für mein VPN undeth0
für mein LAN habe.quelle
ip route get 8.8.8.8 | sed -n '/src/{s/.*src *//p;q}'
gab mir10.1.2.3 uid 1002
. Also füge ich hinzu,| awk '{print $1}'
um nur die IP-Adresse beizubehalten.Auf FreeBSD können Sie verwenden
Dies kann für andere Umgebungen funktionieren, abhängig von Ihrer Einrichtung.
quelle
/etc/resolv.conf
und davon, wie der Netzwerkrouter mit lokalen Hostnamen umgeht. Es ist in Ordnung, dies in Ihrer Umgebung zu verwenden, wenn Sie es testen und es funktioniert. Aber wenn Sie dies tun, bauen Sie ein "sprödes" System auf, das anderen Probleme bereiten wird, wenn Sie dies teilen. Mit Vorsicht verwenden.Unter der Annahme , dass Sie verschiedene Schnittstellen von verschiedenen Namen haben kann , aber dass Sie die erste nicht-localhost ein und Nicht-ipv6 möchten, können Sie versuchen:
quelle
Ich benutze diesen Einzeiler:
Verwendet
ifconfig
(allgemein verfügbar), nimmt keinelocalhost
Adresse an, bindet Sie nicht an einen bestimmten Schnittstellennamen, berücksichtigt IPv6 nicht und versucht, die IP der ersten verfügbaren Netzwerkschnittstelle abzurufen.quelle
oder
quelle
Sie sollten
ip
(anstelle vonifconfig
) verwenden, da es aktuell, gewartet und möglicherweise am wichtigsten für Skriptzwecke ist. Es erzeugt eine konsistente und analysierbare Ausgabe. Es folgen einige ähnliche Ansätze:Wenn Sie die IPv4-Adresse für Ihre Ethernet-Schnittstelle benötigen
eth0
:Als Drehbuch:
Die oben erzeugte Ausgabe erfolgt in CIDR-Notation. Wenn die CIDR-Notation nicht gewünscht ist, kann sie entfernt werden:
Eine weitere Option, bei der IMHO "am elegantesten" ist, ist das Abrufen der IPv4-Adresse für die Schnittstelle, über die die Verbindung zum angegebenen Remote-Host hergestellt wird (in diesem Fall 8.8.8.8). Mit freundlicher Genehmigung von @gatoatigrado in dieser Antwort :
Als Drehbuch:
Dies funktioniert perfekt auf einem Host mit einer einzelnen Schnittstelle, vorteilhafter jedoch auch auf Hosts mit mehreren Schnittstellen und / oder Routenspezifikationen.
ip
wäre mein bevorzugter Ansatz, aber es ist sicherlich nicht der einzige Weg, diese Katze zu häuten. Hier ist ein weiterer Ansatz, der verwendet wird,hostname
wenn Sie etwas Einfacheres / Prägnanteres bevorzugen:Oder, wenn Sie die IPv6-Adresse möchten:
quelle
Ich musste dies in einem Alias tun, um einen Funkserver auf meiner verkabelten Netzwerkkarte zu starten. ich benutzte
quelle
egrep
wird abgeschrieben. Verwenden Siegrep -E
stattdessen.Einige Befehle funktionieren auf Centos 6 oder 7, der folgende Befehl funktioniert auf beiden,
quelle
grep | awk | awk
. Zeile kann gekürzt werden/sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } '
Angenommen, Sie benötigen Ihre primäre öffentliche IP-Adresse, wie sie vom Rest der Welt gesehen wird , versuchen Sie eine der folgenden:
quelle
Dieses Snippet vermeidet das Hardcodieren des Gerätenamens (wie 'eth0') und verwendet
ip
anstelle vonifconfig
:Es wird die IP des ersten aktiven Geräts zurückgegeben, das in der Ausgabe von aufgeführt ist
ip addr
. Abhängig von Ihrem Computer kann dies eine IPv4- oder eine IPv6-Adresse sein.Verwenden Sie zum Speichern in einer Variablen Folgendes:
quelle
Alle Lösungen, die awk / sed / grep verwenden, scheinen für meine Situation zu komplex und hässlich zu sein. Deshalb habe ich diese wirklich einfache Lösung entwickelt, aber Vorsicht, da es einige Annahmen gibt, nämlich die Annahme, dass die LETZTE Schnittstelle die ist, die Sie sind interessiert. Wenn Sie damit einverstanden sind, ist dies ziemlich sauber:
ifconfig | awk '/net / { x = $2 } END { print x }'
Andernfalls könnten Sie eine alberne
if
Anweisung ausführen , um nach einem bestimmten Präfix oder nach beliebigen Kriterien zu suchen.quelle
Einfacher Befehl zur Feineinstellung der IP-Adresse mit der Standardschnittstelle.
Getestet unter allen Unix-Betriebssystemen
quelle
Dies ist möglicherweise nicht die robusteste oder korrekteste Lösung, aber im Gegensatz zu den meisten anderen Lösungen funktioniert der Befehl sowohl unter Linux als auch unter Mac (BSD).
quelle
Wenn Sie nach einer öffentlichen IP-Adresse der Box suchen , können Sie Folgendes verwenden:
dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"
Sie können
dig(1)
Optionen wie-4
oder verwenden,-6
um gezielt nach einer IPv4- oder IPv6-Adresse zu suchen. Google wird eine Antwort in einem Datensatz desTXT
Typs bereitstellen , der bei Vorlage durch Anführungszeichen enthältdig
. Wenn Sie die Variable anschließend mit Dienstprogrammen wie verwenden möchtentraceroute
, müssen Sie etwas wie tr (1) verwenden , um diese Anführungszeichen zu entfernen.Zu den weiteren Optionen gehören
whoami.akamai.net
undmyip.opendns.com
, die mitA
undAAAA
records antworten (anstelle desTXT
obigen Beispiels von Google). Daher müssen die Anführungszeichen nicht entfernt werden:dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short
dig -4 @resolver1.opendns.com -t any myip.opendns.com +short
dig -6 @resolver1.opendns.com -t any myip.opendns.com +short
Hier ist ein Beispielskript, das alle oben genannten Optionen zum Festlegen der Variablen verwendet:
Wenn Sie nach einer privaten IP-Adresse oder nach einem Satz aller der Box zugewiesenen IP-Adressen suchen, können Sie eine Kombination aus
ifconfig
(unter BSD und GNU / Linux),ip addr
(unter GNU / Linux),hostname
(Optionen-i
und-I
ein) verwenden GNU / Linux) und umnetstat
zu sehen, was los ist.quelle
Dies wird alles tun, was Sie wollen
quelle
hostname: invalid option -- 'l'
...