Je recherche une solution en ligne de commande qui me renvoie l'adresse IP principale (première) de l'hôte local, autre que 127.0.0.1
La solution devrait fonctionner au moins pour Linux (Debian et RedHat) et OS X 10.7+
Je suis conscient que ifconfig
est disponible sur les deux, mais sa sortie n'est pas aussi cohérente entre ces plates-formes.
Utilisez grep
pour filtrer l’adresse IP de ifconfig
:
ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'
Ou avec sed
:
ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'
Si vous n'êtes intéressé que par certaines interfaces, wlan0, eth0, etc., alors:
ifconfig wlan0 | ...
Vous pouvez aliaser la commande dans votre .bashrc
à créer votre propre commande appelée myip
par exemple.
alias myip="ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'"
Un moyen beaucoup plus simple est hostname -I
(hostname -i
pour les anciennes versions de hostname
mais voir les commentaires). Cependant, cela ne concerne que Linux.
Pour les machines Linux (pas OS X):
hostname --ip-address
Ce qui suit fonctionnera sous Linux mais pas sous OSX.
Cela ne dépend pas du tout du DNS, et cela fonctionne même si /etc/hosts
n'est pas défini correctement (1
est un raccourci pour 1.0.0.0
):
ip route get 1 | awk '{print $NF;exit}'
ou en évitant awk
et en utilisant le DNS public de Google à 8.8.8.8
pour des raisons d'évidence:
ip route get 8.8.8.8 | head -1 | cut -d' ' -f8
Un moyen moins fiable: (voir commentaire ci-dessous)
hostname -I | cut -d' ' -f1
Pour une configuration plus forte, avec de nombreuses interfaces et de nombreuses adresses IP configurées sur chaque interface, j’ai écrit un script pure bash (non basé sur 127.0.0.1
) pour trouver l’interface correcte et ip, basé sur default route
. Je poste ce script tout en bas de cette réponse.
Comme les deux OS ont bash installé par défaut, il existe une astuce bash pour Mac et Linux:
Le problème de l'environnement local est évité par l'utilisation de 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
Minimal:
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)
}
Utilisation simple:
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
}
Usage:
getMyIP
192.168.1.37
ou, exécutant la même fonction, mais avec un argument:
getMyIP varHostIP
echo $varHostIP
192.168.1.37
set | grep ^varHostIP
varHostIP=192.168.1.37
Nota: Sans argument, cette fonction est affichée sur STDOUT, l'adresse IP et un nouvelle ligne, avec un argument, rien n'est imprimé, mais une variable nommée argument est créée et contient l'adresse IP sans nouvelle ligne.
Nota2: Ceci a été testé sur Debian, LaCie a piraté nas et MaxOs. Si cela ne fonctionne pas dans votre environnement, je serai très intéressé par les retours!
(Non supprimé car basé sur sed
, pas bash
.)
Warn: Il y a un problème avec les locales!
Rapide et petit:
myIP=$(ip a s|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p}')
Éclaté (travail aussi;)
myIP=$(
ip a s |
sed -ne '
/127.0.0.1/!{
s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p
}
'
)
Modifier:
Comment! Cela ne semble pas fonctionner sur Mac OS...
Ok, cela semble fonctionner assez même sur Mac OS que sur mon 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; }')
divisé:
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;
}')
Ce script trouvera d’abord votre route par défaut _ et interface utilisée pour, puis recherchera un réseau local de correspondance ip de passerelle et peuplera des variables. Les deux dernières lignes viennent d’imprimer, quelque chose comme:
Interface : en0
Local Ip : 10.2.5.3
Gateway : 10.2.4.204
Net mask : 255.255.252.0
Run on mac : true
ou
Interface : eth2
Local Ip : 192.168.1.31
Gateway : 192.168.1.1
Net mask : 255.255.255.0
Run on mac : false
Eh bien, voilà:
#!/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 a b c d; 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
sur linux
hostname -I
sur macOS
ipconfig getifaddr en0
Notez que hostname -I
peut renvoyer plusieurs adresses dans un ordre peu fiable (voir man hostname
). Mais pour moi, cela retourne simplement 192.168.1.X
, ce que vous vouliez.
Vous pouvez aussi essayer ceci, même si cela peut simplement vous dire 127.0.0.1
:
hostname -i
ou
hostname -I
$ ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p'
192.168.8.16
Le moyen correct pour interroger les informations réseau utilise ip
:
-o
sortie sur une ligneroute get to
récupère la route du noyau vers une destination8.8.8.8
IP Google, mais peut utiliser l'adresse IP réelle que vous souhaitez atteindrepar exemple. ip
sortie:
8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \ cache
Pour extraire le src
ip, sed
est le plus léger et le plus compatible avec le support regex:
-n
pas de sortie par défaut's/pattern/replacement/p'
correspond au motif et remplace uniquement l'impression.*src \([0-9.]\+\).*
correspond à l'adresse IP src utilisée par le noyau pour atteindre 8.8.8.8
par exemple. résultat final:
192.168.8.16
Je pense qu'aucune des réponses précédentes n'est assez bonne pour moi, car elles ne fonctionnent pas sur une machine récente (Gentoo 2018).
Problèmes que j'ai trouvés avec les réponses précédentes:
ifconfig
qui est déconseillée et, par exemple, ne répertorie pas les adresses IP multiples;awk
pour une tâche simple que sed peut mieux gérer;ip route get 1
n'est pas clair et est en fait un alias pour ip route get to 1.0.0.0
hostname
, qui n'a pas l'option -I
dans toutes les appliances et qui renvoie 127.0.0.1
dans mon cas.Vous pouvez également obtenir l'adresse IP version 4 de eth0 en utilisant cette commande sous Linux
/sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}'
La sortie sera comme ça
[root@localhost Sathish]# /sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}'
192.168.1.22
Cela va obtenir l'interface associée à la route par défaut
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;}'`
En utilisant l'interface découverte ci-dessus, obtenez l'adresse 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
Ordinateur portable Darwin 14.4.0 Kernel Darwin Version 14.4.0: jeu. 28 mai 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 Jeu 3 Sep 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
echo $NET_IF
eth0
echo $NET_IP
192.168.46.10
Utilisation d'autres méthodes Vous pouvez entrer un conflit lorsque plusieurs adresses IP sont définies sur le système . Cette ligne obtient toujours l'adresse IP utilisée par défaut.
ip route get 8.8.8.8 | head -1 | awk '{print $7}'
J'extrais mon commentaire à cette réponse:
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
Il se base sur la réponse de @CollinAnderson qui n'a pas fonctionné dans mon cas.
Interface réseau primaire IP
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
Je dois ajouter à la réponse de Collin Andersons que cette méthode prend également en compte si vous avez deux interfaces et qu'elles apparaissent toutes les deux en haut.
ip route get 1 | awk '{print $NF;exit}'
Je travaillais sur une application avec Raspberry Pi et j'avais besoin de l'adresse IP réellement utilisée, pas seulement de savoir si elle était active ou non. La plupart des autres réponses renverront les deux adresses IP, ce qui n'est pas forcément utile - pour mon scénario de toute façon.
Le moyen le plus rapide d’obtenir votre adresse ipv4 locale sur votre système linux:
hostname -I | awk '{print $1}'
Il y a un paquet de noeud pour tout. C'est multi-plateforme et facile à utiliser.
$ npm install --global internal-ip-cli
$ internal-ip
fe80::1
$ internal-ip --ipv4
192.168.0.3
C'est une approche controversée, mais l'utilisation de npm pour l'outillage devient de plus en plus populaire, qu'on le veuille ou non.
Une autre variante ifconfig
qui fonctionne à la fois sous Linux et OSX:
ifconfig | grep "inet " | cut -f2 -d' '
J'ai parcouru de nombreux liens (StackExchange, AskUbuntu, StackOverflow, etc.) et pris la décision de combiner toutes les meilleures solutions en un seul script Shell.
A mon avis, ces deux QA sont les meilleurs:
Comment obtenir mon adresse IP externe dans un script shell? https://unix.stackexchange.com/q/22615
Comment trouver mon adresse IP interne? https://askubuntu.com/a/604691
Voici ma solution basée sur quelques idées de rsp partagées dans son référentiel ( https://github.com/rsp/scripts/ ).
Certains d’entre vous pourraient dire que ce script est extrêmement volumineux pour une tâche aussi simple, mais j’aimerais le rendre facile et flexible dans l’utilisation le plus possible. Il supporte un fichier de configuration simple permettant de redéfinir les valeurs par défaut.
Il a été testé avec succès sous Cygwin, MINGW et Linux (Red Hat).
Afficher l'adresse IP interne
myip -i
Afficher l'adresse IP externe
myip -e
Code source, également disponible via le lien: https://github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip . Vous trouverez un exemple de fichier de configuration à côté du script principal.
#!/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 - <<HELP
USAGE
$( basename "$0" ) [OPTIONS]
DESCRIPTION
Display the internal and external IP addresses
OPTIONS
-i Display the internal IP address
-e Display the external IP address
-v Turn on verbosity
-h Print this help and exit
HELP
exit
}
die() {
echo "$( basename "$0" ): $@" >&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
Pas sûr que cela fonctionne dans tous les systèmes d'exploitation, essayez-le.
ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}'
ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}'
ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||'
Je viens d'utiliser Noms d'interface réseau , ma commande personnalisée est
[[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
dans mon propre cahier
[flying@lempstacker ~]$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[flying@lempstacker ~]$ [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
192.168.2.221
[flying@lempstacker ~]$
mais si l'interface réseau possède au moins une adresse IP, elle indiquera que toutes les adresses IP lui appartiennent.
par exemple
Ubuntu 16.10
root@yakkety:~# sed -r -n 's@"@@g;s@^VERSION=(.*)@\1@p' /etc/os-release
16.04.1 LTS (Xenial Xerus)
root@yakkety:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
178.62.236.250
root@yakkety:~#
Debian Jessie
root@jessie:~# sed -r -n 's@"@@g;s@^PRETTY_NAME=(.*)@\1@p' /etc/os-release
Debian GNU/Linux 8 (jessie)
root@jessie:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
192.81.222.54
root@jessie:~#
CentOS 6.8
[root@centos68 ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@centos68 ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
162.243.17.224
10.13.0.5
[root@centos68 ~]# ip route get 1 | awk '{print $NF;exit}'
162.243.17.224
[root@centos68 ~]#
Fedora 24
[root@Fedora24 ~]# cat /etc/redhat-release
Fedora release 24 (Twenty Four)
[root@Fedora24 ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
104.131.54.185
10.17.0.5
[root@Fedora24 ~]# ip route get 1 | awk '{print $NF;exit}'
104.131.54.185
[root@Fedora24 ~]#
Il semble que la commande ip route get 1 | awk '{print $NF;exit}'
fournie par link soit plus précise, de plus, plus courte.
En supposant que vous ayez besoin de votre adresse IP principale publique telle qu'elle est vue du reste du monde, essayez l'une de ces options:
wget http://ipecho.net/plain -O - -q
curl http://icanhazip.com
curl http://ifconfig.me/ip
Trouve une adresse IP de cet ordinateur sur un réseau qui est une passerelle par défaut (par exemple, exclut tous les réseaux virtuels, ponts de docker) passerelle internet, passerelle wifi, ethernet
ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
Fonctionne sous Linux.
Tester:
➜ ~ ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
192.168.0.114
➜ reverse-networking git:(feature/type-local) ✗ ifconfig wlp2s0
wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.114 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::d3b9:8e6e:caee:444 prefixlen 64 scopeid 0x20<link>
ether ac:x:y:z txqueuelen 1000 (Ethernet)
RX packets 25883684 bytes 27620415278 (25.7 GiB)
RX errors 0 dropped 27 overruns 0 frame 0
TX packets 7511319 bytes 1077539831 (1.0 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Si vous connaissez l'interface réseau (eth0, wlan, tun0, etc.):
ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2
Si vous avez installé npm
et node
: npm install -g ip && node -e "const ip = require('ip'); console.log(ip.address())"
Sur un Mac, prenez en compte les éléments suivants:
scutil --nwi | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
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]*'
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
Pour Linux, vous avez besoin de cette commande:
ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }'
tapez ceci dans votre shell et vous saurez tout simplement votre adresse IP.
C'est plus facile à lire: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr: