it-swarm.it

Come ottenere il mio indirizzo IP e salvarlo in una variabile in uno script Shell?

Come posso ottenere il mio indirizzo IP e salvarlo in una variabile in uno script Shell?

68
Tom Brito

Non è così facile se si desidera prendere in considerazione wlan e altre interfacce alternative. Se sai per quale interfaccia vuoi l'indirizzo (ad es. Eth0, la prima scheda Ethernet), puoi usare questo:

ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"

In altre parole, procurami le informazioni di configurazione della rete, cerca eth0, ottieni quella riga e la successiva (-A 1), ottieni solo l'ultima riga, ottieni la seconda parte di quella riga quando dividi con :, quindi ottieni la prima parte quando dividi con lo spazio.

31
l0b0

Credo che il modo "strumenti moderni" per ottenere il tuo indirizzo ipv4 sia analizzare 'ip' piuttosto che 'ifconfig', quindi sarebbe qualcosa del tipo:

ip4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
ip6=$(/sbin/ip -o -6 addr list eth0 | awk '{print $4}' | cut -d/ -f1)

o qualcosa di simile.

71
jsbillings

Perché non fare semplicemente IP=$(hostname -I)?

39
Andrei

Se vuoi l'indirizzo di un'interfaccia, il modo più semplice è installare moreutils quindi:

[email protected]:~$ ifdata -pa br0
172.16.1.244

ifdata risponde praticamente a tutte le domande per le quali saresti tentato di analizzare ifconfig output.

Se vuoi scoprire il tuo indirizzo IP come lo vede l'esterno (oltre ogni NAT, ecc.), Ci sono molti servizi che lo faranno. Uno è abbastanza semplice:

[email protected]:~$ curl ifconfig.me
173.167.51.137
27
derobert

Per ottenere gli indirizzi IPv4 e IPv6 e non supporre che l'interfaccia principale sia eth0 (questi giorni em1è più comune ), prova:

ips=$(ip -o addr show up primary scope global |
      while read -r num dev fam addr rest; do echo ${addr%/*}; done)
  • -o utilizza il formato di output a una riga, che è più semplice da elaborare con read, grep, ecc.
  • up esclude i dispositivi che non sono attivi
  • scope global esclude indirizzi privati ​​/ locali come 127.0.0.1 e fe80::/64
  • primary esclude indirizzi temporanei (supponendo che desideri un indirizzo che non cambi)
15
Mikel

Non intendo essere un coglione, ma esiste davvero un modo giusto e questo è tutto. Taglia l'output di ip route Per ottenere solo l'IP sorgente. A seconda dell'IP che si sta tentando di raggiungere, il "mio indirizzo IP" (parole di OP) sarà diverso. Se ti interessa raggiungere la rete Internet pubblica, l'utilizzo del server DNS 8.8.8.8 di Google è piuttosto standard. Così...

La risposta breve è:

ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'

Ecco la spiegazione dettagliata

Se voglio che l'IP che uso raggiunga internet, io uso questo:

[email protected]:~ $ ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
10.55.0.200

Se voglio che l'IP che uso raggiunga qualcosa sul mio VPN , uso questo:

[email protected]:~ $ ip route get 172.31.0.100 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
172.29.0.9

Il prossimo è davvero solo a scopo illustrativo. Ma dovrebbe funzionare su qualsiasi sistema Linux. Quindi, puoi usarlo per dimostrare che, sì, tutte le macchine hanno più indirizzi IP in ogni momento.

Se volessi che l'IP che uso raggiungesse me stesso, userei questo:

[email protected]:~ $ my_ip=$(getent hosts $(cat /etc/hostname) | awk '{print $1; exit}')
[email protected]:~ $ ip route get $my_ip | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
127.0.0.1

Ulteriori informazioni sul comando sed

Prima di tutto lasciami dire che quando scegli gli strumenti unix, provi a scegliere gli strumenti che richiedono il minor numero di pipe. Quindi, mentre alcune risposte verranno reindirizzate da ifconfig a grep a sed a head, ciò raramente è mai necessario. Quando lo vedi, dovrebbe sollevare una bandiera rossa che stai ricevendo consigli da qualcuno con poca esperienza. Ciò non rende la "soluzione" sbagliata. Ma probabilmente potrebbe usare un po 'di razionalizzazione.

Ho scelto sed perché è più conciso rispetto allo stesso flusso di lavoro in awk. (Ne ho un esempio da sbaglio di seguito.) Non credo che nessun altro strumento, ma quei 2 sarebbero appropriati.

Esaminiamo cosa fa sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}':

sed            # the sed executable located via $PATH
-n             # no output unless explicitly requested
'              # begin the command space
/src/          # regex match the string 'src'
{              # begin a block of commands **
s/             # begin a substitution (match)
  .*src *      # match anything leading up to and including src and any number of spaces
  \([^ ]*\)    # define a group containing any number of non spaces
  .*           # match any trailing characters (which will begin with a space because of the previous rule).
/              # begin the substitution replacement
  \1           # reference the content in the first defined group
/              # end the substitution
p              # print (explicitly, remember) the result
;              # designate the end of the command
q              # quit
}              # end the block of commands
'              # end the command space

** all of which will be performed "on match"
  - otherwise only the first command to following the match would be performed "on match"
    - any other commands would be performed whether there was a match or not

Prima usavo sed -n '/src/{s/.*src *//p;q}' Ma un commentatore ha sottolineato che alcuni sistemi hanno dati finali dopo il campo src.

Usando awk

ip route get 8.8.8.8 | \
    awk '{gsub(".*src",""); print $1; exit}'

# or

ip route get 8.8.8.8 | \
    awk '{for(i=1; i<NF; i++){if($i=="src"){i++; print $i; exit}}}'

Maggiori informazioni sulla mia rete

Il mio ifconfig mostra che ho tun0 Per la mia VPN e eth0 Per la mia lan.

[email protected]:~ $ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.55.0.200  netmask 255.255.252.0  broadcast 10.55.3.255
        inet6 fe80::71e6:5d7c:5b4b:fb25  prefixlen 64  scopeid 0x20<link>
        ether b8:27:eb:b2:96:84  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<Host>
        loop  txqueuelen 1  (Local Loopback)

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 172.29.0.9  netmask 255.255.255.255  destination 172.29.0.10
        inet6 fe80::3a8e:8195:b86c:c68c  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)

wlan0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether b8:27:eb:e7:c3:d1  txqueuelen 1000  (Ethernet)
9
Bruno Bronosky
ipa=$(ip route get 8.8.8.8| grep src| sed 's/.*src \(.*\)$/\1/g')

ipa=$(hostname -i|cut -f2 -d ' ')
8
fastrizwaan

Dipende da cosa si intende per proprio indirizzo IP. I sistemi hanno indirizzi IP su diverse sottoreti (a volte diverse per sottorete), alcune delle quali IPv4, altre IPv6 che utilizzano dispositivi come adattatori ethernet, interfacce loopback, tunnel VPN, bridge, interfacce virtuali ...

Intendo l'indirizzo IP tramite il quale un altro dispositivo può raggiungere il tuo computer, devi scoprire quale sottorete è e di quale versione di IP stiamo parlando. Inoltre, tieni presente che a causa di NAT eseguito da firewall/router, l'indirizzo IP di un'interfaccia potrebbe non essere lo stesso di un host remoto che vede una connessione in arrivo dal tuo computer proveniente.

Quando esiste un instradamento di origine elaborato o per protocollo/instradamento delle porte, può essere difficile scoprire quale interfaccia sarebbe utilizzata per comunicare con un computer remoto su un determinato protocollo e anche in questo caso, non vi è alcuna garanzia che l'indirizzo IP di tale interfaccia possa essere indirizzabile direttamente dal computer remoto che desidera stabilire una nuova connessione al computer.

Per IPv4 (probabilmente funziona anche per IPv6), un trucco che funziona in molti unices tra cui Linux per scoprire l'indirizzo IP dell'interfaccia utilizzata per raggiungere un determinato Host è usare un connect (2) su un socket UDP e usare getockname ():

Ad esempio, sul mio computer di casa:

Perl -MSocket -le 'socket(S, PF_INET, SOCK_DGRAM, getprotobyname("udp"));
connect(S, sockaddr_in(1, inet_aton("8.8.8.8")));
print inet_ntoa((sockaddr_in(getsockname(S)))[1]);'

Sarebbe usato per scoprire l'indirizzo IP dell'interfaccia tramite la quale raggiungerei 8.8.8.8 (server DNS di Google). Restituirebbe qualcosa come "192.168.1.123" che è l'indirizzo dell'interfaccia per la route predefinita a Internet. Tuttavia, Google non vedrebbe una richiesta DNS dalla mia macchina come proveniente da quell'indirizzo IP che è privato, poiché c'è NAT eseguito dal mio router a banda larga di casa.

connect () su un socket UDP non invia alcun pacchetto (UDP è senza connessione), ma prepara il socket interrogando la tabella di routing.

8

Su FreeBSD puoi usare

Dig +short `hostname -f`

Questo può funzionare per altri ambienti, dipende dalla tua configurazione.

2
Tigger

Supponendo che tu possa avere varie interfacce con vari nomi ma che vuoi il primo non-localhost e non-ipv6, puoi provare:

ip=`ip addr show |grep "inet " |grep -v 127.0.0. |head -1|cut -d" " -f6|cut -d/ -f1`
2
Nicolas

Dovresti usare ip (invece di ifconfig) poiché è attuale, gestito e forse soprattutto per scopi di scripting, produce un output coerente e analizzabile. Di seguito sono riportati alcuni approcci simili:

Se si desidera l'indirizzo IPv4 per l'interfaccia Ethernet eth0:

$ ip -4 -o addr show eth0 | awk '{print $4}'
192.168.1.166/24  

Come una sceneggiatura:

$ INTFC=eth0  
$ MYIPV4=$(ip -4 -o addr show $INTFC | awk '{print $4}') 
$ echo $MYIPV4
192.168.1.166/24

L'output prodotto sopra è in notazione CIDR. Se la notazione CIDR non è desiderata, può essere rimossa:

$ ip -4 -o addr show eth0 | awk '{print $4}' | cut -d "/" -f 1 
192.168.1.166  

Un'altra opzione che IMHO è "più elegante" ottiene l'indirizzo IPv4 per qualunque interfaccia venga utilizzata per connettersi all'host remoto specificato (8.8.8.8 in questo caso). Per gentile concessione di @gatoatigrado in questa risposta :

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

Come una sceneggiatura:

$ RHOST=8.8.8.8  
$ MYIP=$(ip route get $RHOST | awk '{ print $NF; exit }')
$ echo $MYIP
192.168.1.166

Funziona perfettamente su un host con una singola interfaccia, ma più vantaggiosamente funzionerà anche su host con più interfacce e/o specifiche di route.

ip sarebbe il mio approccio preferito, ma non è certamente l'unico modo per scuoiare questo gatto. Ecco un altro approccio che utilizza hostname se preferisci qualcosa di più semplice/più conciso:

$ hostname --all-ip-addresses | awk '{print $1}'  

Oppure, se si desidera l'indirizzo IPv6:

$ hostname --all-ip-addresses | awk '{print $2}'  
1
Seamus
myip=$(curl -kLs "http://api.ipify.org")

o

myip=$(wget -q "http://api.ipify.org" -O -)
1
Zibri

Uso questo one-liner:

IP=$(/sbin/ifconfig | grep -e "inet:" -e "addr:" | grep -v "inet6" | grep -v "127.0.0.1" | head -n 1 | awk '{print $2}' | cut -c6-)

Utilizza ifconfig (ampiamente disponibile), non accetta localhost indirizzo, non ti lega a un determinato nome di interfaccia, non tiene conto di IPv6 e cerca di ottenere l'IP della prima interfaccia di rete a disposizione.

1

Questo frammento evita di codificare il nome del dispositivo (come 'eth0') e utilizzerà ip invece di ifconfig:

/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/'

Restituirà l'IP del primo dispositivo attivo elencato nell'output di ip addr. A seconda del computer, questo può essere un indirizzo ipv4 o ipv6.

Per memorizzarlo in una variabile, utilizzare:

ip=$(/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/')
0
Philipp Claßen

Supponendo che tu abbia bisogno del tuo IP pubblico primario come 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
0
Putnik

Ho dovuto farlo all'interno di un alias per avviare un server radio sulla mia scheda di rete cablata. ero solito

ip addr | egrep -i "inet.+eth1" | awk -F[\ /] '{print $6}' | tr -d [:space:]
0
user208145

tutte le soluzioni che usano awk/sed/grep sembrano eccessivamente complesse e brutte per la mia situazione ... quindi ho trovato questa soluzione davvero semplice MA attenzione perché fa alcune ipotesi, vale a dire il presupposto che l'interfaccia ULTIMA è quella che stai interessato. se stai bene, allora è abbastanza pulito:

ifconfig | awk '/net / { x = $2 } END { print x }'

altrimenti potresti fare qualche stupida istruzione if per verificare un prefisso specifico o qualsiasi criterio tu possa avere.

0
mad.meesh

Questa potrebbe non essere la soluzione più affidabile o corretta, ma a differenza della maggior parte delle altre soluzioni, il comando funziona sia su Linux che su Mac (BSD).

Host `hostname` | awk '{print $NF}'
0
wisbucky

Alcuni comandi funzionano su centos 6 o 7, il comando seguente funziona su entrambi,

#!/bin/sh

serverip=`/sbin/ifconfig eth0 | grep "inet" | awk '{print $2}' | awk 'NR==1' | cut -d':' -f2`

echo $serverip
0
lakshmikandan

Comando semplice per correggere l'indirizzo IP con l'interfaccia predefinita.

ip route | grep src | awk '{print $NF; exit}'

Testato su tutti i sistemi operativi Unix

0
M.S.Arun

Se stai cercando un indirizzo IP pubblico della casella , puoi utilizzare quanto segue:

  • Dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"

È possibile utilizzare Dig(1) opzioni come -4 O -6 Per cercare specificamente un indirizzo IPv4 o IPv6; Google fornirà una risposta in un record di tipo TXT, che avrà delle virgolette intorno quando sarà presentato da Dig; se vuoi usare successivamente la variabile con utility come traceroute, devi usare qualcosa come tr (1) per rimuovere le citazioni.

Altre opzioni includono whoami.akamai.net E myip.opendns.com, Che rispondono con i record A e AAAA (anziché TXT come nell'esempio precedente di Google ), quindi non richiedono la rimozione delle virgolette:

  • Dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short

  • Dig -4 @resolver1.opendns.com -t any myip.opendns.com +short

  • Dig -6 @resolver1.opendns.com -t any myip.opendns.com +short

Ecco uno script di esempio che utilizza tutte le opzioni sopra per impostare le variabili:

#!/bin/sh
IPANY="$(Dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
GOOGv4="$(Dig -4 @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
GOOGv6="$(Dig -6 @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
AKAMv4="$(Dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short)"
CSCOv4="$(Dig -4 @resolver1.opendns.com -t a myip.opendns.com +short)"
CSCOv6="$(Dig -6 @resolver1.opendns.com -t aaaa myip.opendns.com +short)"
printf '$GOOG:\t%s\t%s\t%s\n' "${IPANY}" "${GOOGv4}" "${GOOGv6}"
printf '$AKAM:\t%s\n$CSCO:\t%s\t%s\n' "${AKAMv4}" "${CSCOv4}" "${CSCOv6}"

Se stai cercando un indirizzo IP privato o un set di tutti gli indirizzi IP assegnati alla casella, puoi utilizzare una combinazione di ifconfig (su BSD e GNU/Linux ), ip addr (Su ​​GNU/Linux), hostname (opzioni -i E -I Su GNU/Linux) e - netstat per vedere cosa sta succedendo.

0
cnst