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
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.
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
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
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!
(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; }')
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.
$ ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p' 192.168.8.16
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
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:
ifconfig
che è deprecato e – per esempio – non elenca IP multipli; 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
hostname
, che non ha l’opzione -I
in tutte le appliance e che restituisce 127.0.0.1
nel mio caso. 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'`
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
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}'