¿Cómo encontrar el servicio de red actualmente conectado desde la línea de comandos?

Me gustaría saber cuál de los servicios de red disponibles (por ejemplo, Ethernet o Wi-Fi ) está activo actualmente. En esta captura de pantalla de Preferencias de red, puede ver que Wi-Fi está actualmente activo (el punto verde):

Preferencias de red

¿Cómo puedo obtener esa información desde la línea de comando?

El networksetupcomando me permite enumerar los servicios de red disponibles:

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

También puede mostrar algunos detalles sobre el servicio, como el nombre del dispositivo:

$ 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)

Desafortunadamente, la información sobre qué servicio está activo (el punto verde de la captura de pantalla) no está disponible en esta información. ¿Hay otro comando que pueda usar para obtener esta información?

Respuestas (10)

Simplemente emite

    ifconfig

Enumere todas las interfaces de red y su estado.

Verdadero: cada registro contiene un statuscampo que tiene activeo inactivecomo valor.
Le dará un resultado falso si está compartiendo su Internet. Supongamos que está compartiendo Internet Ethernet a través de wifi, entonces el estado de Ethernet y wifi será "activo"
Esto no le muestra qué servicio se está utilizando ; tanto wifi como ethernet se mostrarán como "activos" si tiene ambos habilitados y un cable de ethernet enchufado.
Esto es bastante útil para verificar si una conexión no está conectada. Por ejemplo, mi ethernet generalmente solo está conectado en el trabajo. Así que puedo deducir que estoy en casa por no estar en la lista. ifconfig | grep $(networksetup -listnetworkserviceorder | grep 'Ethernet, Device' | sed -E "s/.*(en[0-9]).*/\1/"). Luego puedo cambiar de ubicación en función de que lo anterior esté vacío.
Esto simplemente enumera todas las interfaces de red, no los servicios de red.

Póngalo todo junto, escribí un script para realizar esta tarea:

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

El script primero obtiene una lista de servicios del networksetupcomando, luego verifica si cada servicio está en estado activo desde ifconfig.

Asigne un nombre al script networkservice.sh, por ejemplo, luego ejecútelo para obtener el servicio de red actual en el que se encuentra.

$ bash networkservice.sh
USB 10/100/1000 LAN, en4, 00:e0:4a:6b:4d:0c
Wi-Fi, en0, 8c:85:90:a0:4b:ec
Tuve que canalizar la primera línea para taciterar a través de las interfaces en orden inverso porque a menudo tengo WiFi conectado, así como un adaptador Ethernet USB (que es el dispositivo preferido en la red). En este caso, quiero que se imprima el dispositivo activo preferido:services=$(networksetup -listnetworkserviceorder | grep 'Hardware Port' | tac)
@ghr eso no tiene ningún sentido, networksetup -listnetworkserviceorderya genera primero "el dispositivo más preferido" ...
Parece que terminé modificando un poco el script anterior para que solo imprima 1 servicio, en lugar de cualquier conectado. Tuve que hacerlo tacpara que los servicios posteriores (no preferidos) no sobrescribieran $currentservice. Debería haber sido más claro en ese comentario original.
puede confirmar que esta sigue siendo la mejor respuesta en estos tiempos difíciles cuando la mayoría de las computadoras están conectadas a VPN, ya sea con un túnel completo o no, donde otras respuestas pueden devolver el nombre del dispositivo para el túnel VPN tunX.
Tenga en cuenta que esta secuencia de comandos utiliza nombres de puertos de hardware que generalmente son los mismos que los nombres de los servicios, pero pueden fallar si cambia el nombre manualmente o si tiene varios servicios con el mismo nombre de puerto de hardware, típico de USB Ethernet. Esta esencia tiene una versión modificada para solucionar este problema.

No pretenderé tener la respuesta a esta pregunta ordenada, pero esto, pero esto puede ser útil.

Puede preguntar cómo enrutará actualmente los paquetes a algo:

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

Y luego puede preguntar qué "Servicio de red" está administrando esa interfaz:

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

Pero, sinceramente, dudo que un "Servicios de red" sea uno a uno con un puerto de hardware. Y algunas interfaces, tun0 por ejemplo, no tienen un "Servicio de red". Bueno, al menos a veces no lo hacen.

El scutil --nwicomando enumera las interfaces y scutil --dnsle brinda toda la información de enrutamiento de red que necesitará para asignar etiquetas de interfaz de hardware a rutas de red.

Un poco awky greppuede embellecerlo si necesita escribir la información o reducirla. Comience con el agarre de "if_index" si tiene curiosidad.

No hay mucho que sea simple acerca de las redes, ya que puede tener varias direcciones asignadas a una interfaz y más de una conexión a Internet. La ruta predeterminada suele ser la respuesta correcta, pero con VPN y aplicaciones de codificación estricta, como DNS a través de HTTP y más, Carrie tiene menos peso que hace diez años, cuando macOS se llamaba OS X.

Eso parece útil. ¡Jugaré con eso!

En caso de que alguien más se tropiece con esto como lo hice yo, el código a continuación puede ser más de lo que está buscando.

Esto es para ampliar la respuesta de PeterVP ; también visible aquí .

#!/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
En mi secuencia de comandos, reemplacé la consulta pública con: set public (dig +short myip.opendns.com @resolver1.opendns.com)Mi razonamiento para esto es que es menos probable que un servidor dns (como opendns) esté inactivo que un sitio web y es más rápido. Y eliminé la declaración de sueño. No es necesario esperar la respuesta del servidor dns. Tiempo de ejecución de mi script 177 ms. El tuyo tarda 5,237 segundos, pero hace más, por supuesto. Sigue siendo una gran diferencia.
Gran sugerencia
Esto supone que los servicios de red tienen los mismos nombres que sus puertos de hardware subyacentes. networksetup -getdnsservers ...toma un nombre de servicio de red, que a veces puede ser diferente al puerto de hardware que se le pasó en este script. Puedes verlos todos con-listnetworkserviceorder

No estoy seguro de si esto es útil para alguien, pero como estaba jugando con la misma pregunta, llegué a esta solución:

ifconfig | grep flags=8863 | grep -v bridge

La salida se verá así, y enumera solo los puertos ethernet y wifi que están en uso activo:

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

Si también desea ver la dirección IPv4 asignada:

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

Que produce algo como esto;

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

Otra alternativa:

scutil --nwi

Que muestra los dispositivos de red en línea, la última línea muestra las interfaces de red actualmente activas:

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

El procesamiento adicional, si es necesario, depende de usted. :-)


Nota:

Eso sí, no soy un experto en banderas (8863). Puede encontrar los detalles de la bandera en el archivo de encabezado if.h : Spotlight es su amigo para encontrar "if.h". Encontré el mío, por ejemplo, aquí:

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

que le mostrará lo que significan las banderas (tenga en cuenta: hexadecimal);

#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 */

Sobre la base de las otras respuestas y comentarios (léase: no hice esto), esto se puede condensar en una sola línea:

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

Todo lo que hace es decirnos qué interfaz se está utilizando, dentro del contexto de su orden de interfaz configurada.

Lo uso en un alias de shell:

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

Uso

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

Después de cambiar de interfaz:

$> whichif
(2) Wi-Fi
(Hardware Port: Wi-Fi, Device: en0)
el segundo grepse puede hacer dentro awk:networksetup -listnetworkserviceorder |grep -B1 "$(route get example.com | awk "/interface/ {print \$2}")"
@ccpizza Me encanta!!
@ccpizza El tuyo es mejor, ya que es el mismo comando en el cli y en el alias de shell (wrt ~~citando~~ escapando). He actualizado nuestra respuesta.
Si solo desea el nombre del servicio de red:networksetup -listnetworkserviceorder | awk "/$(route get example.com | awk '/interface/ {print $2}')/{sub(/\([0-9]+\)\ /,\"\",a); print a} {a=\$0}"
Esto también funciona solo para obtener el nombre del servicio de red:networksetup -listnetworkserviceorder |grep -B1 "$(route get 1.1.1.1 | awk '/interface/ {print $2}')" | awk -F'\\) ' '/\([0-9]+\)/ {print $2}'

Tomado de Encontrar el historial detallado de conexiones Wi-Fi desde la línea de comandos de Mac OS X | OSX diario :

Para versiones modernas de Mac OS X, OS X Yosemite 10.10 y posteriores, utilice lo siguiente:

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

Presiona regresar y verás instantáneamente la lista completa de detalles de conexión de red inalámbrica.

Obtiene mucha información sobre el historial de conexiones, incluidos los detalles de la actual.

No es perfecto, pero obtienes la información que estás buscando, ¡y mucha más información adicional!

Está asumiendo una conexión Wi-Fi que no es necesariamente el caso para todos los escenarios.

Aquí hay un guión de concha de pescado que escribí:

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

Muestra todas las interfaces de red activas y datos relevantes.

Comenta lo que no quieres/necesitas

Podría ser más fácil definir una echo_italicfunción de shell en lugar de envolver todos estos echocorreos electrónicos en set_colorllamadas.
Todos los set_colorcomandos se pueden eliminar. Son solo 'decorativos'.
Comandos eliminados set_colory variables colocadas dentro de declaraciones de eco

Solución basada en la entrada proporcionada en todas las otras respuestas.

#################################
# 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}"

La exitentrada en la primera línea asegura que solo se tome el primer dispositivo de red activo en caso de que haya más de uno.