Come ottenere l’indirizzo IP primario del computer locale su Linux e OS X?

Sto cercando una soluzione a riga di comando che mi restituirebbe il primo (primo) indirizzo IP dell’host locale, diverso da 127.0.0.1

La soluzione dovrebbe funzionare almeno per Linux (Debian e RedHat) e OS X 10.7+

Sono consapevole che ifconfig è disponibile su entrambi, ma il suo output non è così coerente tra queste piattaforms.

Usa grep per filtrare l’indirizzo IP da ifconfig :

ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'

O con sed :

ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'

Se ti interessano solo determinate interfacce, wlan0, eth0, ecc. Allora:

ifconfig wlan0 | ...

Puoi alias il comando nel tuo .bashrc per creare il tuo comando chiamato myip per esempio.

alias myip="ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'"

Un modo molto più semplice è hostname -I ( hostname -i per versioni precedenti di hostname ma vedere commenti). Tuttavia, questo è solo su Linux.

Per macchine Linux (non OS X):

 hostname --ip-address 

Quanto segue funzionerà su Linux ma non su OSX.

Questo non si basa affatto sul DNS e funziona anche se /etc/hosts non è impostato correttamente ( 1 è una scorciatoia per 1.0.0.0 ):

 ip route get 1 | awk '{print $NF;exit}' 

oppure evitando awk e utilizzando il DNS pubblico di Google alla 8.8.8.8 per ovvietà:

 ip route get 8.8.8.8 | head -1 | cut -d' ' -f8 

Un modo meno affidabile: (vedi commento sotto)

 hostname -I | cut -d' ' -f1 

Modificato ( 2014-06-01 2018-01-09)

Per una configurazione più forte, con molte interfacce e molti IP configurati su ogni interfaccia, ho scritto uno script bash puro (non basato su 127.0.0.1 ) per trovare l’interfaccia e l’ ip corretti, in base alla default route . Inserisco questo script in fondo a questa risposta.

Intro

Dato che entrambi gli OS hanno installato bash di default, c’è un consiglio bash sia per Mac che per Linux:

Il problema delle impostazioni locali è impedito dall’uso di LANG=C :

 myip= while IFS=$': \t' read -a line ;do [ -z "${line%inet}" ] && ip=${line[${#line[1]}>4?1:2]} && [ "${ip#127.0.0.1}" ] && myip=$ip done< <(LANG=C /sbin/ifconfig) echo $myip 

Mettendo questo in una funzione:

Minimo:

 getMyIP() { local _ip _line while IFS=$': \t' read -a _line ;do [ -z "${_line%inet}" ] && _ip=${_line[${#_line[1]}>4?1:2]} && [ "${_ip#127.0.0.1}" ] && echo $_ip && return 0 done< <(LANG=C /sbin/ifconfig) } 

Uso semplice:

 getMyIP 192.168.1.37 

Fancy in ordine:

 getMyIP() { local _ip _myip _line _nl=$'\n' while IFS=$': \t' read -a _line ;do [ -z "${_line%inet}" ] && _ip=${_line[${#_line[1]}>4?1:2]} && [ "${_ip#127.0.0.1}" ] && _myip=$_ip done< <(LANG=C /sbin/ifconfig) printf ${1+-v} $1 "%s${_nl:0:$[${#1}>0?0:1]}" $_myip } 

Uso:

 getMyIP 192.168.1.37 

oppure, con la stessa funzione, ma con un argomento:

 getMyIP varHostIP echo $varHostIP 192.168.1.37 set | grep ^varHostIP varHostIP=192.168.1.37 

Nota: Senza argomenti, questa funzione viene emessa su STDOUT, l'IP e una nuova riga , con un argomento, non viene stampato nulla, ma viene creata una variabile denominata come argomento che contiene IP senza nuova riga .

Nota2: Questo è stato testato su Debian, LaCie ha hacked nas e MaxOs. Se questo non funziona sotto il tuo ambiente, sarò molto interessato dai feed-backs!

Versione precedente di questa risposta

(Non cancellato perché basato su sed , non bash .)

Avverti: c'è un problema su locales!

Veloce e piccolo:

 myIP=$(ip as|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p}') 

Esploso (funziona anche;)

 myIP=$( ip as | sed -ne ' /127.0.0.1/!{ s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p } ' ) 

Modificare:

Come! Questo sembra non funzionare su Mac OS ...

Ok, questo sembra funzionare abbastanza su Mac OS come su Linux :

 myIP=$(LANG=C /sbin/ifconfig | sed -ne $'/127.0.0.1/ ! { s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p; }') 

diviso:

 myIP=$( LANG=C /sbin/ifconfig | sed -ne $'/127.0.0.1/ ! { s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p; }') 

La mia sceneggiatura (gennaio 2018):

Questo script per prima cosa troverà il percorso e l' interfaccia predefiniti utilizzati, quindi cercherà la rete locale di corrispondenza del gateway IP e popolerà le variabili. Le ultime due righe si stampano, qualcosa del tipo:

 Interface : en0 Local Ip : 10.2.5.3 Gateway : 10.2.4.204 Net mask : 255.255.252.0 Run on mac : true 

o

 Interface : eth2 Local Ip : 192.168.1.31 Gateway : 192.168.1.1 Net mask : 255.255.255.0 Run on mac : false 

Bene, eccolo:

 #!/bin/bash runOnMac=false int2ip() { printf ${2+-v} $2 "%d.%d.%d.%d" \ $(($1>>24)) $(($1>>16&255)) $(($1>>8&255)) $(($1&255)) ;} ip2int() { local _a=(${1//./ }) ; printf ${2+-v} $2 "%u" $(( _a<<24 | ${_a[1]} << 16 | ${_a[2]} << 8 | ${_a[3]} )) ;} while IFS=$' :\t\r\n' read abcd; do [ "$a" = "usage" ] && [ "$b" = "route" ] && runOnMac=true if $runOnMac ;then case $a in gateway ) gWay=$b ;; interface ) iFace=$b ;; esac else [ "$a" = "0.0.0.0" ] && [ "$c" = "$a" ] && iFace=${d##* } gWay=$b fi done < <(/sbin/route -n 2>&1 || /sbin/route -n get 0.0.0.0/0) ip2int $gWay gw while read lhs rhs; do [ "$lhs" ] && { [ -z "${lhs#*:}" ] && iface=${lhs%:} [ "$lhs" = "inet" ] && [ "$iface" = "$iFace" ] && { mask=${rhs#*netmask } mask=${mask%% *} [ "$mask" ] && [ -z "${mask%0x*}" ] && printf -v mask %u $mask || ip2int $mask mask ip2int ${rhs%% *} ip (( ( ip & mask ) == ( gw & mask ) )) && int2ip $ip myIp && int2ip $mask netMask } } done < <(/sbin/ifconfig) printf "%-12s: %s\n" Interface $iFace Local\ Ip $myIp \ Gateway $gWay Net\ mask $netMask Run\ on\ mac $runOnMac 

Puoi anche provare questo, anche se potrebbe solo dirti 127.0.0.1 :

 hostname -i 

o

 hostname -I 

Puoi anche ottenere l’indirizzo IP versione 4 di eth0 usando questo comando in linux

 /sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}' 

L’uscita sarà così

 [[email protected] Sathish]# /sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}' 192.168.1.22 

su linux

 hostname -I 

su macOS

 ipconfig getifaddr en0 

Nota che hostname -I posso restituire più indirizzi in un ordine inaffidabile (vedi man hostname ). Ma per me restituisce solo 192.168.1.X che è quello che volevi.

Soluzione

 $ ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p' 192.168.8.16 

Spiegazione

Il modo corretto per interrogare le informazioni di rete è l’utilizzo di ip :

  • -o output a una linea
  • route get to ottenere il percorso del kernel attuale verso una destinazione
  • 8.8.8.8 IP di Google, ma può utilizzare l’IP reale che si desidera raggiungere

es. uscita ip :

 8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \ cache 

Per estrarre l’ip src , sed è il più leggero e compatibile con il supporto regex:

  • -n nessun output per impostazione predefinita
  • 's/pattern/replacement/p' e solo sostituzione della stampa
  • .*src \([0-9.]\+\).* corrisponde allo src IP usato dal kernel, per raggiungere 8.8.8.8

es. produzione finale:

 192.168.8.16 

Altre risposte

Penso che nessuna delle risposte precedenti sia abbastanza buona per me, visto che non funzionano in una macchina recente (Gentoo 2018).

Problemi che ho trovato con le risposte precedenti:

  • uso della colonna posizionale nell’output del comando;
  • uso di ifconfig che è deprecato e – per esempio – non elenca IP multipli;
  • uso di awk per un compito semplice che sed può gestire meglio;
  • ip route get 1 non è chiaro, ed è in realtà un alias per ip route get to 1.0.0.0
  • uso del comando hostname , che non ha l’opzione -I in tutte le appliance e che restituisce 127.0.0.1 nel mio caso.

Funziona su Linux e OSX

Questo otterrà l’interfaccia associata alla rotta predefinita

 NET_IF=`netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}'` 

Utilizzando l’interfaccia scoperta sopra, ottieni l’indirizzo IP.

 NET_IP=`ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'` 

OSX

 uname -a 

Darwin laptop 14.4.0 Darwin Kernel Versione 14.4.0: gio 28 maggio 11:35:04 PDT 2015; root: xnu-2782.30.5 ~ 1 / RELEASE_X86_64 x86_64

 echo $NET_IF 

EN5

 echo $NET_IP 

192.168.0.130

CentOS Linux

 uname -a 

Linux dev-cil.medfx.local 2.6.18-164.el5xen 1 SMP gio 3 settembre 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU / Linux

 echo $NET_IF 

eth0

 echo $NET_IP 

192.168.46.10

Utilizzo di alcuni altri metodi È ansible immettere un conflitto in cui più indirizzi IP sono definiti sul sistema. Questa riga ottiene sempre l’indirizzo IP per impostazione predefinita utilizzata.

 ip route get 8.8.8.8 | head -1 | awk '{print $7}' 

IP dell’interfaccia di rete principale

 ifconfig `ip route | grep default | head -1 | sed 's/\(.*dev \)\([a-z0-9]*\)\(.*\)/\2/g'` | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1 

Devo aggiungere a Collin Andersons la risposta che questo metodo tiene in considerazione anche se si hanno due interfacce e entrambe si mostrano come sopra.

 ip route get 1 | awk '{print $NF;exit}' 

Ho lavorato su un’applicazione con Raspberry Pi e avevo bisogno dell’indirizzo IP che veniva effettivamente utilizzato non solo se fosse attivo o meno. La maggior parte delle altre risposte restituirà sia l’indirizzo IP che non è necessariamente utile, per il mio scenario comunque.

Non sono sicuro che funzioni in tutti i sistemi operativi, provalo.

 ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}' 
 ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||' 

Il modo più breve per ottenere il tuo indirizzo IPv4 locale sul tuo sistema Linux:

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

Un’altra variante di ifconfig che funziona sia su Linux che su OSX:

 ifconfig | grep "inet " | cut -f2 -d' ' 

Ho passato molti link (StackExchange, AskUbuntu, StackOverflow, ecc.) E ho deciso di combinare tutte le migliori soluzioni in uno script di shell.

A mio parere questi due controlli di qualità sono i migliori:

Come posso ottenere il mio indirizzo IP esterno in uno script di shell? https://unix.stackexchange.com/q/22615

Come trovo il mio indirizzo IP interno? https://askubuntu.com/a/604691

Ecco la mia soluzione basata su alcune idee di rsp condivise nel suo repository ( https://github.com/rsp/scripts/ ).

Alcuni di voi potrebbero dire che questo script è estremamente grande per un compito così semplice, ma mi piacerebbe renderlo più facile e flessibile nell’utilizzo il più ansible. Supporta un semplice file di configurazione che consente di ridefinire i valori predefiniti.

È stato testato con successo con Cygwin, MINGW e Linux (Red Hat).

Mostra l’indirizzo IP interno

 myip -i 

Mostra l’indirizzo IP esterno

 myip -e 

Codice sorgente, disponibile anche dal link: https://github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip . C’è un esempio di file di configurazione, accanto allo script principale.

 #!/bin/bash # ========================================================================= # # Getting both internal and external IP addresses used for outgoing # Internet connections. # # Internal IP address is the IP address of your computer network interface # that would be used to connect to Internet. # # External IP address is the IP address that is visible by external # servers that you connect to over Internet. # # Copyright (C) 2016 Ildar Shaimordanov # # ========================================================================= # Details of the actual implementation are based on the following QA: # # How can I get my external IP address in a shell script? # https://unix.stackexchange.com/q/22615 # # How do I find my internal ip address? # https://askubuntu.com/a/604691 # ========================================================================= for f in \ "$( dirname "$0" )/myip.conf" \ ~/.myip.conf \ /etc/myip.conf do [ -f "$f" ] && { . "$f" break } done # ========================================================================= show_usage() { cat - <&2 exit 2 } # ========================================================================= show_internal="" show_external="" show_verbose="" while getopts ":ievh" opt do case "$opt" in i ) show_internal=1 ;; e ) show_external=1 ;; v ) show_verbose=1 ;; h ) show_usage ;; \? ) die "Illegal option: $OPTARG" ;; esac done if [ -z "$show_internal" -a -z "$show_external" ] then show_internal=1 show_external=1 fi # ========================================================================= # Use Google's public DNS to resolve the internal IP address [ -n "$TARGETADDR" ] || TARGETADDR="8.8.8.8" # Query the specific URL to resolve the external IP address [ -n "$IPURL" ] || IPURL="ipecho.net/plain" # Define explicitly $IPCMD to gather $IPURL using another tool [ -n "$IPCMD" ] || { if which curl >/dev/null 2>&1 then IPCMD="curl -s" elif which wget >/dev/null 2>&1 then IPCMD="wget -qO -" else die "Neither curl nor wget installed" fi } # ========================================================================= resolveip() { { gethostip -d "$1" && return getent ahostsv4 "$1" \ | grep RAW \ | awk '{ print $1; exit }' } 2>/dev/null } internalip() { [ -n "$show_verbose" ] && printf "Internal: " case "$( uname | tr '[:upper:]' '[:lower:]' )" in cygwin* | mingw* | msys* ) netstat -rn \ | grep -w '0.0.0.0' \ | awk '{ print $4 }' return ;; esac local t="$( resolveip "$TARGETADDR" )" [ -n "$t" ] || die "Cannot resolve $TARGETADDR" ip route get "$t" \ | awk '{ print $NF; exit }' } externalip() { [ -n "$show_verbose" ] && printf "External: " eval $IPCMD "$IPURL" $IPOPEN } # ========================================================================= [ -n "$show_internal" ] && internalip [ -n "$show_external" ] && externalip # ========================================================================= # EOF 

Uso solo i nomi dell’interfaccia di rete , il mio comando personalizzato è

 [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' || ip addr show dev eth0 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' 

nel mio taccuino

 [[email protected] ~]$ cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [[email protected] ~]$ [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' || ip addr show dev eth0 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' 192.168.2.221 [[email protected] ~]$ 

ma se l’interfaccia di rete possiede almeno un ip, allora mostrerà che tutti gli IP appartengono ad esso

per esempio

Ubuntu 16.10

 [email protected]:~# sed -r -n '[email protected]"@@g;[email protected]^VERSION=(.*)@\[email protected]' /etc/os-release 16.04.1 LTS (Xenial Xerus) [email protected]:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' || ip addr show dev eth0 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' 178.62.236.250 [email protected]:~# 

Debian Jessie

 [email protected]:~# sed -r -n '[email protected]"@@g;[email protected]^PRETTY_NAME=(.*)@\[email protected]' /etc/os-release Debian GNU/Linux 8 (jessie) [email protected]:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' || ip addr show dev eth0 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' 192.81.222.54 [email protected]:~# 

CentOS 6.8

 [[email protected] ~]# cat /etc/redhat-release CentOS release 6.8 (Final) [[email protected] ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' || ip addr show dev eth0 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' 162.243.17.224 10.13.0.5 [[email protected] ~]# ip route get 1 | awk '{print $NF;exit}' 162.243.17.224 [[email protected] ~]# 

Fedora 24

 [[email protected] ~]# cat /etc/redhat-release Fedora release 24 (Twenty Four) [[email protected] ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' || ip addr show dev eth0 | sed -n -r '[email protected]*inet (.*)/.*brd.*@\[email protected]' 104.131.54.185 10.17.0.5 [[email protected] ~]# ip route get 1 | awk '{print $NF;exit}' 104.131.54.185 [[email protected] ~]# 

Sembra che il comando ip route get 1 | awk '{print $NF;exit}' ip route get 1 | awk '{print $NF;exit}' fornito dal link è più preciso, inoltre, è più breve.

Supponendo che hai bisogno del tuo IP pubblico primario visto dal resto del mondo, prova uno di questi:

 wget http://ipecho.net/plain -O - -q curl http://icanhazip.com curl http://ifconfig.me/ip 

Sto estraendo il mio commento a questa risposta:

 ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p' 

Si basa sulla risposta @CollinAnderson che non ha funzionato nel mio caso.

C’è un pacchetto di nodes per tutto. Eccessivo? Probabilmente. Facile da usare e ricorda? Scommetti.

 $ npm install --global internal-ip-cli $ internal-ip fe80::1 $ internal-ip --ipv4 192.168.0.3 

Se conosci l’interfaccia di rete (eth0, wlan, tun0 ecc.):

 ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2 
 ifconfig | grep "inet addr:" | grep -v "127.0.0.1" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1 
 ifconfig $(netstat -rn | grep -E "^default|^0.0.0.0" | head -1 | awk '{print $NF}') | grep 'inet ' | awk '{print $2}' | grep -Eo '([0-9]*\.){3}[0-9]*' 

Funziona su Mac, Linux e all’interno di Docker Containers:

$ hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print $ hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print $ 1; exit} ‘)

Funziona anche su Makefile come:

LOCAL_HOST := ${shell hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print $1; exit}')}

Per Linux, ciò di cui hai bisogno è questo comando:

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

scrivi questo nella tua shell e semplicemente conoscerai il tuo ip.

Questo è più facile da leggere: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr:

Se hai npm e il node installato: npm install -g ip && node -e "const ip = require('ip'); console.log(ip.address())"

ifconfig | grep ‘inet’ | grep -v ‘127.0.0.1’ | awk ‘{print $ 2}’

Su un Mac, considera quanto segue:

 scutil --nwi | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'