Как получить основной IP-адрес локальной машины на Linux и OS X?
Я ищу решение командной строки, которое вернуло бы мне основной (первый) IP-адрес localhost, кроме 127.0.0.1
решение должно работать по крайней мере для Linux (Debian и RedHat) и OS X 10.7+
Я знаю, что ifconfig доступно на обоих, но его выход не очень согласуются между этими платформами.
30 ответов:
использовать
grepдля фильтрации IP-адресаifconfig:
ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'или
sed:
ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p'если вас интересуют только определенные интерфейсы, wlan0, eth0 и т. д. затем:
ifconfig wlan0 | ...вы можете псевдоним команды в свой
.bashrcдо создать ваша собственная команда называетсяmyipнапример.
alias myip="ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p'"гораздо более простой способ-это
hostname -I(hostname -iдля более старых версийhostnameно см. комментарий). Однако, это только на Linux.
следующее будет работать на Linux, но не OSX.
это не зависит от DNS вообще, и это работает, даже если
/etc/hostsне установлен правильно (1является сокращением для1.0.0.0):ip route get 1 | awk '{print $NF;exit}'или избежать
awkи используя публичный DNS Google в8.8.8.8для очевидности:ip route get 8.8.8.8 | head -1 | cut -d' ' -f8менее надежный способ: (см. комментарий ниже)
hostname -I | cut -d' ' -f1
редактировать (
2014-06-012018-01-09)для более сильной конфигурации, со многими интерфейсами и многими IP, настроенными на каждом интерфейсе, я написал чисто Баш скрипт (не на основе
127.0.0.1) для поиска правильного интерфейса и ip, основанный наdefault route. Я размещаю этот скрипт в самом низу этого ответа.интро
как ОС Баш установленные по умолчанию, есть совет bash для Mac и Linux:
проблема локали предотвращается с помощью
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помещая это в функцию:
минимальные:
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) }простое использование:
getMyIP 192.168.1.37Fancy tidy:
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} "%s${_nl:0:$[${#1}>0?0:1]}" $_myip }использование:
getMyIP 192.168.1.37или, запустив ту же функцию, но с аргументом:
getMyIP varHostIP echo $varHostIP 192.168.1.37 set | grep ^varHostIP varHostIP=192.168.1.37Примечание: без аргументов, эта функция выход на STDOUT, IP и A новая строка, С аргументом ничего не печатается, но переменная с именем в качестве аргумента создается и содержит IP без новая строка.
Nota2: это было проверено на Debian, LaCie взломал nas и MaxOs. Если это не будет работать под вашим окружением, я буду очень заинтересован обратными связями!
более старая версия этого ответа
( не удаляется, потому что на основе
sed, а неbash. )предупреждаю: есть проблема с локалями!
быстрый и маленький:
myIP=$(ip a s|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$//p}')взорвался (тоже работа;)
myIP=$( ip a s | sed -ne ' /127.0.0.1/!{ s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$//p } ' )Edit:
как! Это, кажется, не работает на Mac OS...
ладно, это кажется работа совсем же на Mac OS как на мой 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; }')splitted:
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; }')мой сценарий (Ян 2018):
этот скрипт сначала найдет ваш маршрут по умолчанию и интерфейс используется для, а затем поиск локальной сети IP соответствия шлюз и заполнить переменные. Последние две строки просто напечатать, что-то вроде:
Interface : en0 Local Ip : 10.2.5.3 Gateway : 10.2.4.204 Net mask : 255.255.252.0 Run on mac : trueили
Interface : eth2 Local Ip : 192.168.1.31 Gateway : 192.168.1.1 Net mask : 255.255.255.0 Run on mac : falseвот он:
#!/bin/bash runOnMac=false int2ip() { printf ${2+-v} "%d.%d.%d.%d" \ $((>>24)) $((>>16&255)) $((>>8&255)) $((&255)) ;} ip2int() { local _a=(${1//./ }) ; printf ${2+-v} "%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
вы также можете попробовать это, хотя он может просто сказать вам
127.0.0.1:hostname -iили
hostname -I
вы также можете получить IP-адрес версии 4 eth0 с помощью этой команды в linux
/sbin/ip -4 -o addr show dev eth0| awk '{split(,a,"/");print a[1]}'вывод будет таким
[root@localhost Sathish]# /sbin/ip -4 -o addr show dev eth0| awk '{split(,a,"/");print a[1]}' 192.168.1.22
на linux
hostname -Iна macOS
ipconfig getifaddr en0
отметим, что
hostname -Iможет возвращать несколько адресов в ненадежном порядке (см.man hostname). Но для меня это просто возвращает192.168.1.Xчего вы хотели.
решение
$ ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*//p' 192.168.8.16объяснение
The правильно способ запроса сетевой информации использует
ip:
-oодин-линейный выходroute get toполучить фактический маршрут ядра к месту назначения8.8.8.8Google IP, но может использовать реальный IP, который вы хотите достичьнапример
ipвыход:8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \ cacheчтобы извлечь the
srcip,sed- это ligthest и наиболее совместим с поддержкой регулярных выражений:
-nнет вывода по умолчанию's/pattern/replacement/p'матч шаблон и замена печати только.*src \([0-9.]\+\).*сопоставьте src IP, используемый ядром, чтобы достичь8.8.8.8например, окончательный вывод:
192.168.8.16другие ответы
я думаю, что ни один из предыдущих ответов не достаточно хорошо для меня, так как они не работают в машине (в Gentoo 2018).
вопросы, которые я нашел с предыдущими ответами:
- использование позиционного столбца в выводе команды;
- использование
ifconfigкоторый является устаревшим и-например - не перечислять несколько IP-адресов;- использование
awkдля простой задачи, с которой sed может справиться лучше;ip route get 1неясно, и на самом деле псевдоним дляip route get to 1.0.0.0- использование
hostnameкоманда, которой нет-Iопция во всех устройствах и какой возврат127.0.0.1в моем случае.
это работает на Linux и OSX
это позволит получить интерфейс, связанный с маршрутом по умолчанию
NET_IF=`netstat -rn | awk '/^0.0.0.0/ {thif=substr(,74,10); print thif;} /^default.*UG/ {thif=substr(,65,10); print thif;}'`используя интерфейс, обнаруженный выше, получите 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 -aDarwin laptop 14.4.0 Darwin Kernel Version 14.4.0: чт 28 мая 11: 35:04 PDT 2015; корень: xnu-2782.30.5~1/RELEASE_X86_64 x86_64
echo $NET_IFen5
echo $NET_IP192.168.0.130
CentOS Linux
uname -aLinux dev-cil.medfx.местные 2.6.18-164.el5xen 1 SMP Thu Sep 3 04: 03: 03 EDT 2009 x86_64 x86_64 x86_64 GNU / Linux
echo $NET_IFeth0
echo $NET_IP192.168.46.10
используя некоторые другие методы, вы можете ввести конфликт, в котором в системе определено несколько IP-адресов. Эта строка всегда получает IP-адрес по умолчанию используется.
ip route get 8.8.8.8 | head -1 | awk '{print }'
первичный сетевой интерфейс IP
ifconfig `ip route | grep default | head -1 | sed 's/\(.*dev \)\([a-z0-9]*\)\(.*\)//g'` | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1
самый короткий способ получить локальный ipv4-адрес в вашей системе linux:
hostname -I | awk '{print }'
Я должен добавить к ответу Коллина Андерсона, что этот метод также учитывает, если у вас есть два интерфейса, и они оба отображаются как вверх.
ip route get 1 | awk '{print $NF;exit}'Я работал над приложением с Raspberry Pi и нуждался в IP-адресе, который фактически использовался не только независимо от того, был ли он включен или нет. Большинство других ответов вернут оба IP-адреса, что не обязательно полезно - для моего сценария в любом случае.
Не уверен, что это работает во всех ОС, попробуйте.
ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print }'
другое
ifconfigвариант, который работает как на Linux, так и на OSX:ifconfig | grep "inet " | cut -f2 -d' '
Я прошел через множество ссылок (StackExchange, AskUbuntu, StackOverflow и т. д.) и пришел к решению объединить все лучшие решения в один сценарий оболочки.
на мой взгляд, эти два QAs являются лучшими из увиденных:
как я могу получить свой внешний IP-адрес в сценарии оболочки? https://unix.stackexchange.com/q/22615
как найти мой внутренний ip-адрес? https://askubuntu.com/a/604691
вот мой решение, основанное на некоторых идеях rsp, разделенных в его репозитории (https://github.com/rsp/scripts/).
некоторые из вас могут сказать, что этот сценарий очень огромный для такой простой задачи, но я хотел бы сделать его легким и гибким в использовании насколько это возможно. Он поддерживает простой файл конфигурации, позволяющий переопределить значения по умолчанию.
он был успешно протестирован под Cygwin, MINGW и Linux (Red Hat).
показать внутренний IP адрес
myip -iпоказать внешний IP-адрес
myip -eисходный код, также доступный по ссылке:https://github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip. пример конфигурационного файла находится рядом с основным скриптом.
#!/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 "" )/myip.conf" \ ~/.myip.conf \ /etc/myip.conf do [ -f "$f" ] && { . "$f" break } done # ========================================================================= show_usage() { cat - <<HELP USAGE $( basename "" ) [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 "" ): $@" >&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 "" && return getent ahostsv4 "" \ | grep RAW \ | awk '{ print ; 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 }' 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
Я просто использовать Имена Сетевых Интерфейсов мои пользовательские команды
[[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@p'в моей записной книжке
[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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@p' 192.168.2.221 [flying@lempstacker ~]$но если сетевой интерфейс владеет хотя бы одним ip, то он покажет, что все ip принадлежат ему
Ubuntu 16.10
root@yakkety:~# sed -r -n 's@"@@g;s@^VERSION=(.*)@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@p' 178.62.236.250 root@yakkety:~#Debian Jessie
root@jessie:~# sed -r -n 's@"@@g;s@^PRETTY_NAME=(.*)@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@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.*@@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@@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 ~]#похоже на то команда
ip route get 1 | awk '{print $NF;exit}'предоставлен ссылке точнее, более того, он более короткий.
предполагая, что вам нужен ваш основной общественные IP как видно из остального мира, попробуйте любой из них:
wget http://ipecho.net/plain -O - -q curl http://icanhazip.com curl http://ifconfig.me/ip
есть пакет узлов для всего. Перебор? Возможно. Простой в использовании и запомнить? Ясное дело!.
$ npm install --global internal-ip-cli $ internal-ip fe80::1 $ internal-ip --ipv4 192.168.0.3
я извлекаю свой комментарий к этому ответу:
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$//p'Он основан на ответе @CollinAnderson, который не работал в моем случае.
Если вы знаете сетевой интерфейс (eth0, wlan, tun0 и т. д.):
ifconfig eth0 | grep addr: | awk '{ print }' | 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 }' | grep -Eo '([0-9]*\.){3}[0-9]*'
работает на Mac, Linux и внутри контейнеров Docker:
$ hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*//p' | awk '{print1$; выход}')работает на
Makefileкак:
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]*).*//p' | awk '{print ; exit}')}
для linux вам нужна следующая команда:
ifconfig |sed -n 2p|awk '{ print }'|awk -F : '{ print }'введите это в своей оболочке, и вы просто узнаете свой ip.
Если у вас
npmиnodeустановлено :npm install -g ip && node -e "const ip = require('ip'); console.log(ip.address())"
на Mac, рассмотрим следующее:
scutil --nwi | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
Comments