Wie kann ich die Liste aller aktiven Netzwerkschnittstellen programmgesteuert abrufen?

Mein Ziel ist es, die IP-Adresse für Ethernet auf einem Gerät zu ermitteln. Aber unter der Annahme, dass es Verbindungen wie WLAN und USB-Ethernet gibt, gibt es einen bestimmten Weg, nur um die Ethernet-IP zu erhalten?

Auf einer Shell würde ich tun, networksetup -listallhardwareportswas mir eine Zuordnung von Hardware-Port zu Gerät geben würde. Von dort aus würde ich das Gerät für Hardware-Port: Ethernet suchen und dann ifaddr struct verwenden, um meine IP zu erhalten.

Ich kenne den ifaddr-Teil, bitte schlagen Sie vor, wie der erste Teil programmgesteuert ausgeführt wird. Gibt es auch einen alternativen Ansatz?

Sie können den scutilBefehl verwenden, um aktive Netzwerkschnittstellen mit ihren IPv4- und 6-Adressen aufzulisten:scutil --nwi

Antworten (2)

Es kann verschiedene Möglichkeiten geben, das zu erreichen, was Sie fragen, aber ich werde dies einfach hier rauswerfen.

Ich habe ein MacBook Pro, das keinen eingebauten Ethernet-Port hat, also verwende ich in meinen Beispielen Hardware Port: Wi-Fi, da ich dies in beiden Beispielen unten getestet habe und es funktioniert hat, aber Sie können es in Hardware Port ändern : Ethernet , wenn dies die Ausgabe von
networksetup -listallhardwareportszeigt.

Wenn Sie nur die IP-Adresse des Zielgeräts an ausgeben möchten stdout, verwenden Sie das folgende Beispiel:

$ ipconfig getifaddr $(networksetup -listallhardwareports | awk '/Hardware Port: Wi-Fi/{getline; print $2}')
192.168.1.100

Wenn Sie es einer Variablen in einem Skript zuweisen möchten , verwenden Sie das folgende Beispiel:

ipAddress="$(ipconfig getifaddr $(networksetup -listallhardwareports | awk '/Hardware Port: Wi-Fi/{getline; print $2}'))"

Erläuterung:

Die relevante Ausgabe von networksetup -listallhardwareportsfür mein System ist:

Hardware Port: Wi-Fi
Device: en0
Ethernet Address: 28:cf:e3:10:a4:cd

(Hinweis: Das ist nicht meine echte MAC-Adresse)

Mit $(...)der Befehlssubstitution, um etwas zu übergeben, ipconfig getifaddr <args>bestimme ich den Gerätenamen des Hardware-Ports mit der Ausgabe von networksetup -listallhardwareportsund leite |ihn durch , der nach der Funktion awksucht und diese verwendet, die die nächste Zeile nach der Übereinstimmung liest und an übergeben wird , which in essence gibt den zweiten Teil der Zeile nach dem match aus , was in diesem Fall ist und der im ersten Beispiel als Argument übergeben wird , zB . Die Ausgabe davon ist die IP-Adresse.Hardware Port: Wi-Figet lineprint $2en0ipconfig getifaddripconfig getifaddr en0

Im zweiten Beispiel $(...)wird eine zweite Befehlsersetzung um die komplexe Befehlszeile verwendet, die für das Beispiel verwendet wird, um sie der Variablenstdout zuzuweisen, wenn sie in einem Skript verwendet wird .ipAddress

Hinweis: Dies soll wirklich ein Beispiel sein, da ich es nicht so codiert habe, dass das Gerät ausgefallen ist. Mit anderen Worten, wenn das Gerät keine IP-Adresse hat, wird stdoutder ipAddress Variablen im Skript nichts ausgegeben und nichts zugewiesen . Obwohl es im Skript codiert werden kann, um zu testen, ob die ipAddress Variable leer ist oder nicht, und entsprechend zu handeln.

Oh danke, aber ich suche nach einer mehr Syscall / C-basierten Lösung ....
Wenn Sie den Namen der Schnittstelle kennen, können Sie Folgendes verwenden: ` ipconfig getifaddr en0`

Verwenden Sie SCNetworkInterfaceCopyAll, um eine Liste der Schnittstellen zu erhalten, und filtern Sie dann mit SCNetworkInterfaceGetInterfaceType diejenigen heraus, die kein Ethernet zurückgeben . Von dort können Sie das Gateway und die Maske usw. erhalten - in Python verwende ich dafür Netifaces .

Es ist eine bewährte Vorgehensweise bei AskDifferent, nicht nur Links, sondern wichtige Ausschnitte von den Seiten bereitzustellen, auf die Sie verweisen. Allzu oft sterben Links und Ihre Antwort wird ohne Kontext wertlos. Fühlen Sie sich frei, wesentliche Codezeilen und Hintergrundinformationen zu kopieren und einzufügen, solange sie richtig zugeordnet sind.