Wie finde ich den aktuell verbundenen Netzwerkdienst über die Befehlszeile?

Ich möchte wissen, welcher der verfügbaren Netzwerkdienste (z. B. Ethernet oder WLAN ) gerade aktiv ist. In diesem Screenshot aus den Netzwerkeinstellungen können Sie sehen, dass Wi-Fi derzeit aktiv ist (der grüne Punkt):

Netzwerkeinstellungen

Wie kann ich diese Informationen von der Befehlszeile abrufen?

Mit dem networksetupBefehl kann ich die verfügbaren Netzwerkdienste auflisten:

$ networksetup -listallnetworkservices
An asterisk (*) denotes that a network service is disabled.
Ethernet
FireWire
Wi-Fi

Es kann auch einige Details zum Dienst anzeigen, z. B. den Gerätenamen:

$ networksetup -listnetworkserviceorder
An asterisk (*) denotes that a network service is disabled.
(1) Ethernet
(Hardware Port: Ethernet, Device: en0)

(2) FireWire
(Hardware Port: FireWire, Device: fw0)

(3) Wi-Fi
(Hardware Port: Wi-Fi, Device: en1)

Leider ist die Info, welcher Dienst aktiv ist (der grüne Punkt aus dem Screenshot), in dieser Info nicht verfügbar. Gibt es einen anderen Befehl, mit dem ich diese Informationen abrufen könnte?

Antworten (10)

Einfach ausgeben

    ifconfig

Listen Sie alle Netzwerkschnittstellen und ihren Status auf.

True – jeder Datensatz enthält ein statusFeld, das entweder activeoder inactiveals Wert hat.
Es wird Ihnen ein falsches Ergebnis geben, wenn Sie Ihr Internet teilen. Angenommen, Sie teilen Ethernet-Internet über WLAN, dann ist der Status für Ethernet und WLAN "aktiv".
Dies zeigt Ihnen nicht, welcher Dienst verwendet wird - sowohl WLAN als auch Ethernet werden als "aktiv" angezeigt, wenn Sie beide aktiviert und ein Ethernet-Kabel angeschlossen haben.
Dies ist sehr praktisch, um zu überprüfen, ob eine Verbindung nicht besteht. Zum Beispiel ist mein Ethernet im Allgemeinen nur bei der Arbeit verbunden. Ich kann also ableiten, dass ich zu Hause bin, wenn dies nicht in der Liste steht. ifconfig | grep $(networksetup -listnetworkserviceorder | grep 'Ethernet, Device' | sed -E "s/.*(en[0-9]).*/\1/"). Dann kann ich den Standort wechseln, basierend darauf, dass das obige leer ist.
Dies listet einfach alle Netzwerkschnittstellen auf, nicht Netzwerkdienste.

Zusammenfassend habe ich ein Skript geschrieben, um diese Aufgabe zu erfüllen:

#!/bin/bash

while read -r line; do
    sname=$(echo "$line" | awk -F  "(, )|(: )|[)]" '{print $2}')
    sdev=$(echo "$line" | awk -F  "(, )|(: )|[)]" '{print $4}')
    #echo "Current service: $sname, $sdev, $currentservice"
    if [ -n "$sdev" ]; then
        ifout="$(ifconfig "$sdev" 2>/dev/null)"
        echo "$ifout" | grep 'status: active' > /dev/null 2>&1
        rc="$?"
        if [ "$rc" -eq 0 ]; then
            currentservice="$sname"
            currentdevice="$sdev"
            currentmac=$(echo "$ifout" | awk '/ether/{print $2}')

            # may have multiple active devices, so echo it here
            echo "$currentservice, $currentdevice, $currentmac"
        fi
    fi
done <<< "$(networksetup -listnetworkserviceorder | grep 'Hardware Port')"

if [ -z "$currentservice" ]; then
    >&2 echo "Could not find current service"
    exit 1
fi

Das Skript ruft zuerst eine Dienstliste vom networksetupBefehl ab und prüft dann, ob sich jeder Dienst im aktiven Status von befindet ifconfig.

Benennen Sie das Skript networkservice.shbeispielsweise in und führen Sie es dann aus, um den aktuellen Netzwerkdienst abzurufen, auf dem Sie sich befinden.

$ bash networkservice.sh
USB 10/100/1000 LAN, en4, 00:e0:4a:6b:4d:0c
Wi-Fi, en0, 8c:85:90:a0:4b:ec
Ich musste die erste Zeile tacleiten, um die Schnittstellen in umgekehrter Reihenfolge zu durchlaufen, da ich oft WiFi sowie einen USB-Ethernet-Adapter (das das bevorzugte Gerät im Netzwerk ist) angeschlossen habe. In diesem Fall möchte ich, dass das am meisten bevorzugte aktive Gerät gedruckt wird:services=$(networksetup -listnetworkserviceorder | grep 'Hardware Port' | tac)
@ghr das macht keinen Sinn, networksetup -listnetworkserviceordergibt schon "das am meisten bevorzugte Gerät" zuerst aus ...
Sieht so aus, als hätte ich das obige Skript ein wenig geändert, sodass es nur 1 Dienst ausdruckt und keine verbundenen. Ich musste, tacdamit spätere (nicht bevorzugte) Dienste $currentservice. Hätte in diesem ursprünglichen Kommentar klarer sein sollen.
kann bestätigen, dass dies in diesen schwierigen Zeiten, in denen die meisten Computer mit VPN verbunden sind, entweder vollständig getunnelt oder nicht, immer noch die beste Antwort ist, während andere Antworten möglicherweise den Gerätenamen für den VPN-Tunnel zurückgeben tunX.
Beachten Sie, dass dieses Skript Hardware-Portnamen verwendet, die im Allgemeinen mit Dienstnamen identisch sind, aber fehlschlagen können, wenn Sie manuell umbenennen oder wenn Sie mehrere Dienste mit demselben Hardware-Portnamen haben, was typisch für USB-Ethernet ist. Dieser Kern enthält eine geänderte Version, um dieses Problem zu beheben.

Ich werde nicht vorgeben, die Antwort auf diese Frage sortiert zu haben, aber dies, aber dies könnte hilfreich sein.

Sie können fragen, wie Pakete derzeit an etwas weitergeleitet werden:

$ route get example.com | grep interface
interface: en8

Und dann können Sie fragen, welcher "Netzwerkdienst" diese Schnittstelle verwaltet:

$ networksetup -listnetworkserviceorder | grep en8
(Hardware Port: Broadcom NetXtreme Gigabit Ethernet Controller, Device: en8)

Aber ehrlich gesagt bezweifle ich, dass ein "Network Services" eins zu eins mit einem Hardwareport geht. Und einige Schnittstellen, zum Beispiel tun0, haben keinen "Netzwerkdienst". Nun, zumindest manchmal tun sie das nicht.

Der scutil --nwiBefehl listet Schnittstellen auf und scutil --dnsder Befehl gibt Ihnen alle Netzwerk-Routing-Informationen, die Sie benötigen, um Hardware-Schnittstellenbezeichnungen Netzwerkrouten zuzuordnen.

Ein wenig awkund grepkann es verschönern, wenn Sie die Informationen skripten oder reduzieren müssen. Beginnen Sie mit dem Greifen nach "if_index", wenn Sie neugierig sind.

Beim Netzwerken gibt es nicht viel Einfaches, da einer Schnittstelle mehrere Adressen und mehr als eine Verbindung zum Internet zugewiesen werden können. Die Standardroute ist oft die richtige Antwort, aber mit VPN und Apps, die Dinge wie DNS über HTTP und mehr fest codieren, hat Standard-Carrie weniger Gewicht als vor zehn Jahren, als macOS noch OS X hieß.

Das sieht nützlich aus - ich werde damit herumspielen!

Nur für den Fall, dass jemand anders darüber stolpert, wie ich es getan habe, ist der folgende Code möglicherweise eher das, wonach Sie suchen.

Dies soll die Antwort von PeterVP erweitern ; auch hier sichtbar .

#!/bin/sh

clear
sExternalMACALService="http://dns.kittell.net/macaltext.php?address="

# List all Network ports
NetworkPorts=$(ifconfig -uv | grep '^[a-z0-9]' | awk -F : '{print $1}')
#echo $NetworkPorts

# Function to convert IP Subnet Mask to CIDR
mask2cdr ()
{
# Assumes there's no "255." after a non-255 byte in the mask
local x=${1##*255.}
set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
x=${1%%$3*}
echo $(( $2 + (${#x}/4) ))
}

# Get remote/public IP address
remoteip=$(dig +short myip.opendns.com @resolver1.opendns.com)

# Get computer name
computername=$(scutil --get ComputerName)

# Get serial number
sSerialNumber=$(system_profiler SPHardwareDataType |grep "Serial Number (system)" |awk '{print $4}'  | cut -d/ -f1)
#echo $sSerialNumber

# Get operating system name and version - Start
OSvers1=$( sw_vers -productVersion | cut -d. -f1 )
OSvers2=$( sw_vers -productVersion | cut -d. -f2 )
OSvers3=$( sw_vers -productVersion | cut -d. -f3 )
case $OSvers2 in
8)
OSName="Mountain Lion"
;;
9)
OSName="Mavericks"
;;
10)
OSName="Yosemite"
;;
11)
OSName="El Capitan"
;;
12)
OSName="Sierra"
;;
default)
OSName="Unknown"
;;
esac
# Get operating system name and version - Stop


echo "$computername"
echo "--------------"
echo "      Computer OS:  Mac OS X - $OSName $OSvers1.$OSvers2.$OSvers3"
echo "    Computer Name:  $computername"
echo "Current User Name:  $(whoami)"
echo "    Serial Number:  $sSerialNumber"

if [[ $remoteip ]]; then
echo "Remote IP Address:  $remoteip\n"
else
echo "Remote IP Address:  Unable To Determine\n"
fi

for val in $NetworkPorts; do   # Get for all available hardware ports their status
activated=$(ifconfig -uv "$val" | grep 'status: ' | awk '{print $2}')
#echo $activated
label=$(ifconfig -uv "$val" | grep 'type' | awk '{print $2}')
#echo $label
#ActiveNetwork=$(route get default | grep interface | awk '{print $2}')
ActiveNetworkName=$(networksetup -listallhardwareports | grep -B 1 "$label" | awk '/Hardware Port/{ print }'|cut -d " " -f3- | uniq)
#echo $ActiveNetwork
#echo $ActiveNetworkName
state=$(ifconfig -uv "$val" | grep 'status: ' | awk '{print $2}')
#echo $state
ipaddress=$(ifconfig -uv "$val" | grep 'inet ' | awk '{print $2}')
# echo $ipaddress

if [[ -z $(ifconfig -uv "$val" | grep 'link rate: ' | awk '{print $3, $4}' | sed 'N;s/\n/ up /' ) ]]; then
networkspeed="$(ifconfig -uv "$val" | grep 'link rate: ' | awk '{print $3}' ) up/down"
else
networkspeed="$(ifconfig -uv "$val" | grep 'link rate: ' | awk '{print $3, $4}' | sed 'N;s/\n/ up /' ) down"
fi

#echo $networkspeed
macaddress=$(ifconfig -uv "$val" | grep 'ether ' | awk '{print $2}')
#echo $macaddress
macal=$(curl -s "$sExternalMACALService$macaddress")
#echo $macal
quality=$(ifconfig -uv "$val" | grep 'link quality:' | awk '{print $3, $4}')
#echo $quality
netmask=$(ipconfig getpacket "$val" | grep 'subnet_mask (ip):' | awk '{print $3}')
#echo $netmask
router=$(ipconfig getpacket "$val" | grep 'router (ip_mult):' | sed 's/.*router (ip_mult): {\([^}]*\)}.*/\1/')
#echo $router
DHCPActive=$(networksetup -getinfo "Wi-Fi" | grep DHCP)
#echo $DHCPActive
dnsserver=$(networksetup -getdnsservers "$ActiveNetworkName" | awk '{print $1, $2}' | sed 'N;s/\n//' )
#echo $dnsserver

if [ "$activated" = 'active' ]; then
#echo "Network Port is Active"
if [[ $ipaddress ]]; then
echo "$ActiveNetworkName ($val)"
echo "--------------"
# Is this a WiFi associated port? If so, then we want the network name
if [ "$label" = "Wi-Fi" ]; then
WiFiName=$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | grep '\sSSID:' | sed 's/.*: //')
#echo $WiFiName
echo "     Network Name:  $WiFiName"
fi

echo "       IP Address:  $ipaddress"
echo "      Subnet Mask:  $netmask"
echo "           Router:  $router"
echo "          IP CIDR:  $ipaddress/$(mask2cdr $netmask)"

if [[ -z $dnsserver ]]; then
if [[ $DHCPActive ]]; then
echo "       DNS Server:  Set With DHCP"
else
echo "       DNS Server:  Unknown"
fi
else
echo "       DNS Server:  $dnsserver"
fi

echo "      MAC-address:  $macaddress ($macal)"
echo "    Network Speed:  $networkspeed"
echo "     Link quality:  $quality"
echo " "
fi

# Don't display the inactive ports.
fi

done
In meinem Skript habe ich die öffentliche Abfrage ersetzt durch: set public (dig +short myip.opendns.com @resolver1.opendns.com)Meine Begründung dafür ist, dass ein DNS-Server (wie opendns) weniger wahrscheinlich ausfällt als eine Website und schneller ist. Und ich habe die Schlafanweisung entfernt. Sie müssen nicht auf die Antwort des DNS-Servers warten. Ausführungszeit für mein Skript 177 ms. Deins dauert 5,237 Sekunden, macht aber natürlich mehr. Immer noch ein großer Unterschied.
Toller Vorschlag
Dies setzt voraus, dass Netzwerkdienste dieselben Namen haben wie ihre zugrunde liegenden Hardwareports. networksetup -getdnsservers ...nimmt einen Netzwerkdienstnamen an, der sich manchmal von dem Hardwareport unterscheiden kann, der ihm in diesem Skript übergeben wird. Sie können sie alle mit sehen-listnetworkserviceorder

Ich bin mir nicht sicher, ob dies für jemanden hilfreich ist, aber als ich an derselben Frage herumbastelte, kam ich zu dieser Lösung:

ifconfig | grep flags=8863 | grep -v bridge

Die Ausgabe sieht in etwa so aus und listet nur die Ethernet-Ports und das WLAN auf, die aktiv verwendet werden:

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500

Wenn Sie auch die zugewiesene IPv4-Adresse sehen möchten:

ifconfig | grep 'flags=8863\|inet ' | grep -v 'bridge\|127.0.0.1'

Was so etwas hervorbringt;

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    inet 192.168.2.147 netmask 0xffffff00 broadcast 192.168.2.255
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    inet 192.168.2.244 netmask 0xffffff00 broadcast 192.168.2.255

Eine weitere Alternative:

scutil --nwi

Was die Online-Netzwerkgeräte zeigt, zeigt die letzte Zeile tatsächlich die derzeit aktiven Netzwerkschnittstellen:

Network information

IPv4 network interface information
     en0 : flags      : 0x5 (IPv4,DNS)
           address    : 192.168.2.147
           reach      : 0x00000002 (Reachable)
     en1 : flags      : 0x5 (IPv4,DNS)
           address    : 192.168.2.244
           reach      : 0x00000002 (Reachable)

   REACH : flags 0x00000002 (Reachable)

IPv6 network interface information
   No IPv6 states found


   REACH : flags 0x00000000 (Not Reachable)

Network interfaces: en0 en1

Die weitere Verarbeitung, falls erforderlich, obliegt Ihnen. :-)


Notiz:

Wohlgemerkt, ich bin kein Experte für die Flaggen (8863). Sie finden die Flag-Details in der if.h- Header-Datei – Spotlight ist Ihr Freund beim Auffinden von „if.h“. Ich habe meine z.B. hier gefunden:

/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/net/if.h

was Ihnen zeigt, was die Flags bedeuten (denken Sie daran: hexadezimal);

#define IFF_UP          0x1             /* interface is up */
#define IFF_BROADCAST   0x2             /* broadcast address valid */
#define IFF_DEBUG       0x4             /* turn on debugging */
#define IFF_LOOPBACK    0x8             /* is a loopback net */
#define IFF_POINTOPOINT 0x10            /* interface is point-to-point link */
#define IFF_NOTRAILERS  0x20            /* obsolete: avoid use of trailers */
#define IFF_RUNNING     0x40            /* resources allocated */
#define IFF_NOARP       0x80            /* no address resolution protocol */
#define IFF_PROMISC     0x100           /* receive all packets */
#define IFF_ALLMULTI    0x200           /* receive all multicast packets */
#define IFF_OACTIVE     0x400           /* transmission in progress */
#define IFF_SIMPLEX     0x800           /* can't hear own transmissions */
#define IFF_LINK0       0x1000          /* per link layer defined bit */
#define IFF_LINK1       0x2000          /* per link layer defined bit */
#define IFF_LINK2       0x4000          /* per link layer defined bit */
#define IFF_ALTPHYS     IFF_LINK2       /* use alternate physical connection */
#define IFF_MULTICAST   0x8000          /* supports multicast */

Aufbauend auf den anderen Antworten und Kommentaren (sprich: Ich habe das nicht gemacht) kann dies in einer einzigen Zeile zusammengefasst werden:

networksetup -listnetworkserviceorder |grep -B1 "$(route get example.com | awk "/interface/ {print \$2}")"

Es teilt uns lediglich mit, welche Schnittstelle im Rahmen Ihrer konfigurierten Schnittstellenbestellung verwendet wird.

Ich verwende es in einem Shell-Alias:

# determine which network interface is being used
alias whichif='networksetup -listnetworkserviceorder  |grep -B1 "$(route get example.com | awk "/interface/ {print \$2}")"'

Verwendung

$> whichif
(1) Thunderbolt Ethernet Slot 2
(Hardware Port: Thunderbolt Ethernet Slot 2, Device: en7)

Nach Schnittstellenwechsel:

$> whichif
(2) Wi-Fi
(Hardware Port: Wi-Fi, Device: en0)
die zweite grepkann innen durchgeführt werden awk:networksetup -listnetworkserviceorder |grep -B1 "$(route get example.com | awk "/interface/ {print \$2}")"
@ccpizza Ich liebe es!!
@ccpizza Deins ist besser, da es der gleiche Befehl auf der CLI und im Shell-Alias ​​ist (wrt ~~quoting~~ escaping). Ich habe unsere Antwort aktualisiert.
Wenn Sie nur den Netzwerkdienstnamen möchten:networksetup -listnetworkserviceorder | awk "/$(route get example.com | awk '/interface/ {print $2}')/{sub(/\([0-9]+\)\ /,\"\",a); print a} {a=\$0}"
Dies funktioniert auch, um nur den Netzwerkdienstnamen zu erhalten:networksetup -listnetworkserviceorder |grep -B1 "$(route get 1.1.1.1 | awk '/interface/ {print $2}')" | awk -F'\\) ' '/\([0-9]+\)/ {print $2}'

Entnommen aus Finden Sie den detaillierten Wi-Fi-Verbindungsverlauf von der Befehlszeile von Mac OS X | OSXDaily :

Verwenden Sie für moderne Versionen von Mac OS X, OS X Yosemite 10.10 und neuer Folgendes:

defaults read /Library/Preferences/SystemConfiguration/com.apple.airport.preferences |grep LastConnected -A 7

Drücken Sie die Eingabetaste und Sie sehen sofort die umfassende Liste der Verbindungsdetails zum drahtlosen Netzwerk.

Sie erhalten viele Informationen über den Verlauf der Verbindungen, einschließlich der Details für die aktuelle Verbindung.

Nicht perfekt, aber Sie erhalten die Informationen, nach denen Sie suchen - und viele zusätzliche Informationen mehr!

Sie gehen von einer Wi-Fi-Verbindung aus, was nicht unbedingt für alle Szenarien der Fall ist.

Hier ist ein Fish Shell-Skript, das ich geschrieben habe:

function netinfo -d "get network information"

  # Get public ip address
  set public (dig +short myip.opendns.com @resolver1.opendns.com)
  set hostname (uname -n)

  if test -z "$public" # We got an empty string, meaning:
    set public "No Internet connection available"
  end

  echo ''
  echo "    Public IP: $public"
  echo "     Hostname: $hostname"
  echo ''

  # Get all available hardware ports
  set ports (ifconfig -uv | grep '^[a-z0-9]' | awk -F : '{print $1}')

  # Get for all available hardware ports their status
  for val in $ports
    set activated (ifconfig -uv $val | grep 'status: ' | awk '{print $2}')

    # We want information about active network ports...
    if test $activated = 'active' ^/dev/null
      set ipaddress (ifconfig -uv $val | grep 'inet ' | awk '{print $2}')

      # and of these, the ones with an IP-address assigned to it
      if test -n "$ipaddress" ^/dev/null

        # Do we have an IP address?
        # Then give us the information
        set label (ifconfig -uv $val | grep 'type' | awk '{print $2}')
        set macaddress (ifconfig -uv $val | grep 'ether ' | awk '{print $2}')
        set quality (ifconfig -uv $val | grep 'link quality:' | awk '{print $3, $4}')
        set netmask (ipconfig getpacket $val | grep 'subnet_mask (ip):' | awk '{print $3}')
        set router (ipconfig getpacket $val | grep 'router (ip_mult):' | sed 's/.*router (ip_mult): {\([^}]*\)}.*/\1/')
        set dnsserver (ipconfig getpacket $val | grep 'domain_name_server (ip_mult):' | sed 's/.*domain_name_server (ip_mult): {\([^}]*\)}.*/\1/')

        # Header for the network interfaces
        echo -n $label ; echo -n ' ('; echo -n $val ; echo ')'
        echo "--------------"

        # Is this a WiFi associated port? If so, then we want the network name
        switch $label
          case Wi-Fi
            # Get WiFi network name
            set wifi_name (/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | grep '\sSSID:' | sed 's/.*: //')
            echo " Network Name: $wifi_name"
            # Networkspeed for Wi-Fi
            set networkspeed (/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | grep lastTxRate: | sed 's/.*: //' | sed 's/$/ Mbps/')
          case '*'
            # Networkspeed  for other ports
            set networkspeed (ifconfig -uv $val | grep 'link rate:' | awk '{print $3, $4}')
        end

        echo "   IP-address: $ipaddress"
        echo "  Subnet Mask: $netmask"
        echo "       Router: $router"
        echo "   DNS Server: $dnsserver"
        echo "  MAC-address: $macaddress"
        echo "Network Speed: $networkspeed"
        echo " Link quality: $quality"
        echo ''
      end

      # Don't display the inactive ports.
    else if test $activated = 'inactive' ^/dev/null
    end
  end
end

Es zeigt alle aktiven Netzwerkschnittstellen und relevanten Daten.

Kommentieren Sie aus, was Sie nicht wollen/brauchen

Es könnte einfacher sein, eine echo_italicShell-Funktion zu definieren, anstatt all diese echos in set_colorAufrufe zu packen.
Alle set_colorBefehle können entfernt werden. Sie sind nur "dekorativ".
Befehle entfernt set_colorund Variablen in Echo-Anweisungen eingefügt

Lösung basierend auf den Eingaben in allen anderen Antworten.

#################################
# get MacOS network device name
function get_network_device() {
  scutil --nwi | awk -F': ' '/Network interfaces/ {print $2;exit;}'
}

#################################
# get MacOS network service name: takes network device name as 1st arg
function get_service_name() {
  /usr/sbin/networksetup -listnetworkserviceorder | awk -v DEV="$1" -F': |,' '$0~ DEV  {print $2;exit;}'
}

NETWORK_DEVICE_NAME="$(get_network_device)"
NETWORK_SERVICE_NAME="$(get_service_name "$NETWORK_DEVICE_NAME")"

echo "${NETWORK_SERVICE_NAME}"

Das exitin in der ersten Zeile stellt sicher, dass nur das erste aktive Netzwerkgerät genommen wird, falls es mehr als eines gibt.