Quale comando del terminale per ottenere solo l'indirizzo IP e nient'altro?


118

Sto cercando di utilizzare solo l'indirizzo IP (inet) come parametro in uno script che ho scritto.

C'è un modo semplice in un terminale Unix per ottenere solo l'indirizzo IP, invece di guardare attraverso ifconfig?


Sì, o qualsiasi altro identificatore univoco della macchina, suppongo.
Mason

1
ottieni un'opzione non valida su hostname -i?
Ken

4
hostname non è affidabile come ifconfig
joel

2
joel ha ragione, specialmente tu stavi parlando di MAC OS e poi di Ubuntu
zackaryka

2
Quando si sfogliano le risposte seguenti, tenere presente che l'output di ip -o addressè molto più facile da lavorare rispetto all'output di ip address.
jlh

Risposte:


177

Puoi scrivere uno script che restituisca solo l'IP come:

/sbin/ifconfig eth0 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}'

Per MAC:

ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d\  -f2

O per il sistema Linux

hostname -i | awk '{print $3}' # Ubuntu 

hostname -i # Debian

4
hostname -isul mio ritorna:::1 127.0.1.1 192.168.1.100
Libro di Zeus

1
Su Debian ho un solo ip. Quindi l'utilizzo hostnamenon è portatile.
Timofey Stolbov

1
Dice che -i e -I sono entrambe opzioni illegali
Mason

3
In sintesi: il primo metodo dipende dall'adattatore, che non è sempre lo stesso. Il secondo, per me, mostra due indirizzi IP e gli ultimi due non funzionano su Mac.
Matt

4
ifconfig è deprecato e inaffidabile qui, ad esempio grep fallisce su Debian 9 (stretch) perché non restituisce più "inet addr: 172.17.0.4", ma restituisce solo "inet 172.17.0.4". Utilizza invece "ip" come descritto in stackoverflow.com/a/26694162/72717 .
jamshid

61

Questo ti darà tutte le interfacce IPv4, incluso il loopback 127.0.0.1:

ip -4 addr | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

Questo mostrerà solo eth0:

ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

E in questo modo puoi ottenere indirizzi IPv6:

ip -6 addr | grep -oP '(?<=inet6\s)[\da-f:]+'

Solo eth0IPv6:

ip -6 addr show eth0 | grep -oP '(?<=inet6\s)[\da-f:]+'

La grep -oPfallisce il busybox v1.24.1: opzione non valida - P
Pro Backup

1
grep non è installato su quasi tutti i conatiner docker per prod. Quindi, sebbene questi siano tutti buoni comandi, non saranno utili sui contenitori :-(
AndyGee

1
La migliore risposta per il mio caso particolare. È necessario uno -Pswitch per le espressioni regolari Perl o altrimenti non possiamo utilizzare il (?<=inet\s)token lookbehind . Puoi ottenere un risultato simile eseguendo grep -oe 'inet [0-9\.]\+'o grep -oe 'inet6 [0-9a-f:]\+'ma in questo modo non riesco a sbarazzarmi della prima parola. Nei man greprapporti SuSE tale -Pflag è sperimentale.
Jorge Bellon

Questa è la migliore risposta. ifconfig è deprecato da diversi anni sulla maggior parte dei sistemi operativi.
pozcircuitboy

2
Una versione più breve del secondo comando:ip -4 a show eth0 | grep -Po 'inet \K[0-9.]*'
tukusejssirs il

41

In generale, non è mai garantito che un sistema abbia un solo indirizzo IP, ad esempio, puoi avere sia connessioni ethernet che wlan e, se hai una connessione VPN attiva, avrai ancora un altro indirizzo IP.

Linux

Su Linux, hostname -Ielencherà gli indirizzi IP correnti. Affidarsi a esso restituendo sempre un solo indirizzo IP molto probabilmente non funzionerà come previsto in alcuni scenari (ad esempio, un collegamento VPN è attivo), quindi un modo più affidabile sarebbe convertire il risultato in un array e quindi eseguire il loop sugli elementi:

ips=($(hostname -I))

for ip in "${ips[@]}"
do
    echo $ip
done

OSX

Su OSX, se conosci l'interfaccia , potresti usare:

~$ ipconfig getifaddr en0
192.168.1.123

che restituirà solo l'indirizzo IP.

Oppure puoi scorrere i possibili nomi di interfaccia, iniziando con un suffisso, ad esempio en:

for NUMBER in $(seq 0 5); do
    ip=`ipconfig getifaddr en$NUMBER`
    if [ -n "$ip" ]; then
        myip="$ip"
        break
    fi
done

echo $myip

Inoltre, ottenere l'indirizzo IP diventa non deterministico nel caso in cui vengano stabilite connessioni via cavo e wifi, quando una macchina ha più di un'interfaccia ethernet o quando sono presenti tunnel VPN.

Ottenere l'IP esterno

Se hai bisogno dell'IP esterno, puoi interrogare un servizio in modalità testo, ad esempio curl https://ipecho.net/plainrestituirebbe un IP esterno in testo normale .

E un modo ancora più veloce per ottenere l'IP esterno è interrogare un server DNS noto:

dig @ns1-1.akamaitech.net ANY whoami.akamai.net +short

come ottenere l'indirizzo IP della LAN?
diEcho

17
hostname -I  

Questo comando ti darà l'indirizzo IP esatto che desideri in Ubuntu.


rispetto al numero di risposte già esistenti (e votate in alto), non credo che questa risposta aggiungerà alcun valore ...
Mischa

4
anche sul nome host di Centos -I (i maiuscola)
zzapper

1
questo in realtà mi ha aiutato - la nota "i" maiuscola era la chiave
ChronoFish

2
Lo stesso, questo fa il lavoro perfettamente senza strumenti aggiuntivi e senza bisogno di chiamare quindici binari di fila per ripulire l'output. Grazie !
Ulrar

11

Nelle ultime versioni di Ubuntu ( 14.04 - 16.04 ), questo comando ha fatto il trucco per me.

hostname -I | awk '{print $1}'

1
Dalla pagina di manuale: "[...] Questa opzione enumera tutti gli indirizzi configurati su tutte le interfacce di rete. [...] Non fare ipotesi sull'ordine dell'uscita". L'ultima frase ti dice che print $1può o non può darti il ​​risultato corretto.
0 0

7

Se hai un ambiente limitato, puoi usare questo comando:

ip -4 addr show dev eth0 | grep inet | tr -s " " | cut -d" " -f3 | head -n 1

3
O anche:ip -o -4 addr show dev eth0 | cut -d' ' -f7 | cut -d'/' -f1
Jose Alban

Si hai ragione. Ma attenzione, se eth0 ha più di un indirizzo IP, questo li mostra tutti.
caglar

bash-4.4 # ip -4 addr mostra dev eth0 | grep inet | tr -s "" | cut -d "" -f3 | head -n 1172.17.0.3/16 Quindi non va bene con il / 16
AndyGee

Aggiungendo un all'anello: ip -4 addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1. Sia per v4 che v6:ip addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1
Sumit Murari

Se il nome dell'interfaccia non è noto (o differisce tra le piattaforme) ma cerchi l' indirizzo IP privato, invece di ip -4 addr show eth0 | grep ineteseguire:ip -4 addr show | grep 192
cyberbird

6

Per ottenere solo l'indirizzo IP su Mac OS X puoi digitare il seguente comando:

ipconfig getifaddr en0

4

Il comando ifconfigè deprecato e dovresti usare il ipcomando su Linux.

Inoltre ip ati darà l'ambito sulla stessa linea dell'IP, quindi è più facile da usare.

Questo comando ti mostrerà il tuo IP globale (esterno):

ip a | grep "scope global" | grep -Po '(?<=inet )[\d.]+'

Tutti gli IPv4 (anche 127.0.0.1):

ip a | grep "scope" | grep -Po '(?<=inet )[\d.]+'

Tutti gli IPv6 (anche :: 1):

ip a | grep "scope" | grep -Po '(?<=inet6 )[\da-z:]+'

4

Possiamo semplicemente usare solo 2 comandi (ifconfig + awk) per ottenere solo l'IP (v4) che vogliamo in questo modo:

Su Linux, supponendo di ottenere l'indirizzo IP eth0dall'interfaccia, eseguire il seguente comando:

/sbin/ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'

Su OSX, supponendo di ottenere l'indirizzo IP en0dall'interfaccia, eseguire il seguente comando:

/sbin/ifconfig en0 | awk '/inet /{print $2}'

Per conoscere il nostro IP pubblico / esterno, aggiungi questa funzione in ~/.bashrc

whatismyip () {
    curl -s "http://api.duckduckgo.com/?q=ip&format=json" | jq '.Answer' | grep --color=auto -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"
}

Allora corri whatismyip


4

Per stampare solo l'indirizzo IP di eth0, senza altro testo:

ifconfig eth0 | grep -Po '(?<=inet )[\d.]+'

Per determinare la tua interfaccia principale (perché potrebbe non essere "eth0"), utilizza:

route | grep ^default | sed "s/.* //"

Le due righe precedenti possono essere combinate in un unico comando come questo:

ifconfig `route | grep ^default | sed "s/.* //"` \
  | grep -Po '(?<=inet )[\d.]+'

3

Volevo qualcosa di semplice che funzionasse come un alias Bash. Ho scoperto che hostname -Ifunziona meglio per me (hostname v3.15). hostname -irestituisce l'IP di loopback, per qualche motivo, ma hostname -Imi fornisce l'IP corretto per wlan0 e senza dover inviare l'output tramite grep o awk. Uno svantaggio è che hostname -Iprodurrà tutti gli IP, se ne hai più di uno.


2

Questo farebbe il trucco in un Mac:

ping $(ifconfig en0 | awk '$1 == "inet" {print $2}')

Questo si è risolto ping 192.168.1.2nella mia macchina.

Suggerimento : $(...)significa eseguire tutto ciò che è all'interno delle parentesi in una subshell e restituirlo come valore.


2

In man hostnamec'è ancora più facile modo che escludendo automaticamente loopback IP e mostrando solo spazio elenco di tutti assegnati a indirizzi IP host separati:

root@srv:~# hostname --all-ip-addresses
11.12.13.14 192.168.15.19 

root@srv:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
   inet6 ::1/128 scope host 
   valid_lft forever preferred_lft forever
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
  link/void 
  inet 11.12.13.14/32 scope global venet0:0
  inet 192.168.15.19/32 scope global venet0:1

2

Puoi anche usare il seguente comando:

ip route | grep src

NOTA: funzionerà solo se disponi di connettività a Internet.


2

Poche risposte sembrano essere utilizzando il più recente ipdi comando (sostituzione ifconfig): ecco uno che usi ip addr, grepe awkper stampare semplicemente l'indirizzo IPv4 associato con l' wlan0interfaccia di:

ip addr show wlan0|grep inet|grep -v inet6|awk '{print $2}'|awk '{split($0,a,"/"); print a[1]}'

Sebbene non sia la soluzione più compatta o stravagante, è (probabilmente) facile da capire (vedere la spiegazione di seguito) e da modificare per altri scopi, come ottenere gli ultimi 3 ottetti dell'indirizzo MAC in questo modo:

ip addr show wlan0|grep link/ether|awk '{print $2}'|awk '{split($0,mac,":"); print mac[4] mac[5] mac[6]}'

Spiegazione: ip addr show wlan0 restituisce le informazioni associate all'interfaccia di rete denominata wlan0, che dovrebbe essere simile a questa:

4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether dc:a6:32:04:06:ab brd ff:ff:ff:ff:ff:ff
    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::d340:5e4b:78e0:90f/64 scope link 
       valid_lft forever preferred_lft forever

Prossimi grep inetfiltra le linee che non contengono "inet" (IPv4 e IPv6 configurazione) e grep -v inet6filtra le linee rimanenti che fanno contenere "inet6", che dovrebbe tradursi in una singola linea come questa:

    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0

Infine, il primo awkestrae il campo "172.18.18.1/24" e il secondo rimuove l'abbreviazione della maschera di rete, lasciando solo l'indirizzo IPv4.

Inoltre, penso valga la pena ricordare che se stai creando script, spesso ci sono molti strumenti più ricchi e / o più robusti per ottenere queste informazioni, che potresti invece voler usare. Ad esempio, se si usa Node.js c'è ipaddr-linux, se si usa Ruby c'è linux-ip-parser, ecc.

Vedi anche /unix/119269/how-to-get-ip-address-using-shell-script


1

Usa il seguente comando:

/sbin/ifconfig $(netstat -nr | tail -1 | awk '{print $NF}') | awk -F: '/inet /{print $2}' | cut -f1 -d ' '

1

Ecco la mia versione, in cui puoi passare un elenco di interfacce, ordinate per priorità:

getIpFromInterface()
{
    interface=$1
    ifconfig ${interface}  > /dev/null 2>&1 && ifconfig ${interface} | awk -F'inet ' '{ print $2 }' | awk '{ print $1 }' | grep .
}

getCurrentIpAddress(){
    IFLIST=(${@:-${IFLIST[@]}})
    for currentInterface in ${IFLIST[@]}
    do
        IP=$(getIpFromInterface  $currentInterface)
        [[ -z "$IP" ]] && continue
    echo ${IP/*:}
    return
    done
}

IFLIST=(tap0 en1 en0)
getCurrentIpAddress $@

Quindi, se sono connesso con VPN, Wifi ed ethernet, verrà restituito il mio indirizzo VPN (sull'interfaccia tap0). Lo script funziona sia su linux che su osx e può accettare argomenti se vuoi sovrascrivere IFLIST

Nota che se vuoi usare IPV6, dovrai sostituire "inet" con "inet6".


1

Finisco sempre per aver bisogno di questo nei momenti più inaspettati e, senza fallo, finisco per cercare discussioni come questa su SO. Quindi ho scritto un semplice script per ottenere indirizzi IPv4 tramite netstat, chiamato echoip- puoi trovarlo qui . La bash per gli indirizzi di rete ha questo aspetto, ottiene anche il tuo indirizzo pubblico da ipecho.net:

IPV4='\d+(\.\d+){3}'
INTERFACES=`netstat -i | grep -E "$IPV4" | cut -d ' ' -f 1`
INTERFACE_IPS=`netstat -i | grep -oE "$IPV4"`

for i in "${!INTERFACES[@]}"; do
  printf "%s:\t%s\n" "${INTERFACES[$i]}" "${INTERFACE_IPS[$i]}"
done

Lo echoipscript produce un output come questo:

$ echoip
public: 26.106.59.169
en0:    10.1.10.2

1

usa questo script di una riga: ifconfig | grep "inet " | grep -v 127.0.0.1|awk 'match($0, /([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/) {print substr($0,RSTART,RLENGTH)}' mac e linux (testati in ubuntu) funzionano entrambi.


Bello che funzioni su entrambi. Inoltre puoi chiamarlo con ifconfig en0o ifconfig eth1ecc. Se conosci l'interfaccia che desideri :)
jaygooby

1

Preferisco non usarlo awke tale negli script .. ipha la possibilità di output in JSON.

Se tralasci, $interfaceottieni tutti gli indirizzi IP:

ip -json addr show $interface | \
  jq -r '.[] | .addr_info[] | select(.family == "inet") | .local'

Mi piace il modo in cui il risultato del comando in formato strutturale json come il comando ip. ecco un altro modo per ottenere l'indirizzo IP simile a quello sopra bash ip -j addr show eth0 | jp "[0].addr_info[?family== 'inet'].local | [0]"
Jack Liu Shurui il

0
ip addr|awk '/eth0/ && /inet/ {gsub(/\/[0-9][0-9]/,""); print $2}'

mostra tutti i tuoi IP


0

Su Redhat 64bit, questo problema ha risolto per me.

ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }'

o questo: curl ifconfig.me
Statham

0
#!/bin/sh
# Tested on Ubuntu 18.04 and Alpine Linux 
# List IPS of following network interfaces:
# virtual host interfaces
# PCI interfaces
# USB interfaces
# ACPI interfaces
# ETH interfaces
for NETWORK_INTERFACE in $(ls /sys/class/net -al | grep -iE "(/eth[0-9]+$|vif|pci|acpi|usb)" | sed -E "s@.* ([^ ]*) ->.*@\1@"); do 
    IPV4_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet addr[: ]+|inet[: ]+)' | sed -E "s@\s*(inet addr[: ]+|inet[: ]+)([^ ]*) .*@\2@")
    IPV6_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet6 addr[: ]+|inet6[: ]+)' | sed -E "s@\s*(inet6 addr[: ]+|inet6[: ]+)([^ ]*) .*@\2@")
    if [ -n "$IPV4_ADDRESSES" ] || [ -n "$IPV6_ADDRESSES" ]; then
        echo "NETWORK INTERFACE=$NETWORK_INTERFACE"
        for IPV4_ADDRESS in $IPV4_ADDRESSES; do 
            echo "IPV4=$IPV4_ADDRESS"
        done
        for IPV6_ADDRESS in $IPV6_ADDRESSES; do 
            echo "IPV6=$IPV6_ADDRESS"
        done
    fi
done

0

Quando si cerca il proprio indirizzo IP esterno su un host NAT, alcune risposte suggeriscono di utilizzare metodi basati su HTTP come ifconfig.mead esempio:

$ curl ifconfig.me/ip

Negli anni ho visto molti di questi siti andare e venire, trovo questo metodo basato su DNS più robusto:

$ dig +short myip.opendns.com @resolver1.opendns.com

Ho questo pratico alias nel mio ~/.bashrc:

alias wip='dig +short myip.opendns.com @resolver1.opendns.com'

0

Questi due modi hanno funzionato per me:

Per ottenere l'indirizzo IP della tua interfaccia eth0. Sostituisci eth0 nell'esempio seguente con il nome della tua interfaccia. ifconfig eth0 | grep -w "inet" | tr -s " " | cut -f3 -d" "

Utilizzo del nome host: questo ti darà inet ie IPAddress del tuo etho. usando -Vi fornirò il valore inet di tutte le interfacce ovunque questo valore sia presente.

hostname -i


-1
curl ifconfig.co 

Questo restituisce solo l'indirizzo IP del tuo sistema.


1
Ciò richiede una connessione Internet funzionante e restituirà il tuo indirizzo IP visibile pubblicamente, che potrebbe essere o meno quello che desideri.
jlh

-2

Lo userei Hostname -Lper ottenere solo l'IP da utilizzare come variabile in uno script.


Forse stavi cercando di dire hostname -io hostname -I?
jlh

user@linux:~$ Hostname -L -bash: Hostname: command not found user@linux:~$ 1. Il capitale Hè sbagliato 2. Assolutamente no-L
Sabrina
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.