Jak uzyskać podstawowy adres IP komputera lokalnego w systemie Linux i OS X? [Zamknięte]


339

Szukam rozwiązania wiersza polecenia, które zwróciłoby mi podstawowy (pierwszy) adres IP hosta lokalnego, inny niż 127.0.0.1

Rozwiązanie powinno działać przynajmniej w systemie Linux (Debian i RedHat) i OS X 10.7+

Wiem, że ifconfigjest dostępny na obu, ale jego wyniki nie są tak spójne między tymi platformami.


2
Czy chcesz tylko adres IP swojej sieci lokalnej? tj. 192.168.0.12
Chris Seymour

Tak, lokalny adres IP, pierwszy z nich, ponieważ może mieć więcej niż jeden, ale mógłbym żyć nawet z listą. W tej chwili z przyjemnością obsługuję tylko adresy IPv4 i ignoruję IPv6, ponieważ chcę tylko wygenerować skrót.
sorin,

2
Jak definiujesz „podstawowy”? Jeśli myślisz „adres IP, który znajduje się w tej samej podsieci, co moja domyślna trasa”, musisz to trochę zaprogramować. Ale co jeśli maszyna nie ma domyślnej trasy, ale nadal ma> 1 adres IP?
ghoti

4
Spróbować curl -4 ifconfig.co. Odpowie na Twój zewnętrzny adres IP4.
asmaier

Odpowiedzi:


475

Służy grepdo filtrowania adresu IP z ifconfig:

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

Lub z sed:

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

Jeśli interesują Cię tylko niektóre interfejsy, wlan0, eth0 itp., To:

ifconfig wlan0 | ...

Możesz dokonać aliasu polecenia w swoim, .bashrcaby utworzyć własne polecenie, myipna przykład o nazwie .

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

Znacznie prostszym sposobem jest hostname -I( hostname -idla starszych wersji, hostnameale patrz komentarze). Jest to jednak tylko w systemie Linux.


5
Zauważ też, że w OSX sed używa -Eopcji Extended RE, a nie -ropcji w stylu GNU .
ghoti

1
Ciekawy; Nie zdawałem sobie sprawy, że GNU sed jest obsługiwany -E. Najnowsze wersje FreeBSD dodały -ropcję jako alias -Eułatwiającą przenoszenie skryptu, ale aktualizacja nie została jeszcze przeniesiona do OSX, który ostatnio sprawdziłem nadal używa wersji sed z wydania FreeBSD sprzed kilku lat. Nie jestem pewien, który dokładnie, ponieważ OSX kilka lat przyjmował kod źródłowy FreeBSD. Uważam, że stosowanie -Emiało być porównywalny do grep„s -Eopcja. Nie mam pojęcia, dlaczego ludzie GNU zdecydowali się na to -r.
ghoti

1
@ghoti Zmieniłem odpowiedź, aby użyć, -Eaby mieć pewność przenośności, pomyślałbyś, że --helpi man pageszostanie zaktualizowana .. to spowodowało lekkie zamieszanie dla mnie wcześniej w innym pytaniu przy użyciu-E
Chris Seymour

1
Znalazłem problem, chociaż działa w systemie OS X, zwraca więcej niż jeden adres IP, listę adresów IP. Wydaje się, że pierwszy jest właściwy, ale i tak złamałoby to moją logikę. Zobacz gist.github.com/ssbarnea/31b9dcb0f8fd528b958c - zwraca również vnic, które są aktywne, ale używane przez równoległe.
sorin

13
OSX: ipconfig getifaddr en0
parleer

232

Następujące będą działać w systemie Linux, ale nie OSX.

To w ogóle nie opiera się na DNS i działa, nawet jeśli /etc/hostsnie jest ustawione poprawnie ( 1jest skrótem 1.0.0.0):

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

lub unikanie awkpublicznego DNS-u Google i korzystanie z niego 8.8.8.8dla oczywistości:

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

Mniej niezawodny sposób: (patrz komentarz poniżej)

hostname -I | cut -d' ' -f1

8
Metoda, która otrzymuje pierwszy adres wygenerowany przez hostname -Ijest niewiarygodna, ponieważ (zgodnie z dokumentacją) nie można przyjmować żadnych założeń dotyczących kolejności adresów. Więc może to być jakaś sieć wewnętrzna (na przykład sieć, w której żyją maszyny wirtualne). Druga metoda wydaje się dobra.
Adam Ryczkowski

3
To powinna być zaakceptowana odpowiedź, ponieważ RHEL 7 nie zawiera już ifconfig.
Andrew

10
Dla mnie ip route get 1 | awk '{print $(NF-2);exit}'działa, gdy dołączam UID do outptut
Hritik

13
TO (pierwsze) jest jedynym poprawnym rozwiązaniem . Jest ważne , aby przeczytać IP specjalnie z interfejsu związanego z trasy domyślnej. W przeciwnym razie prawdopodobnie uzyskasz jakiś bezwartościowy adres wewnętrzny.
Jan Hudec

12
nie działało to dla mnie, ale zostało wystarczająco zamknięte:ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
estani

230

W przypadku maszyn linuxowych (nie OS X):

hostname --ip-address

10
Działa to tylko wtedy, gdy nazwa jest w DNS. Jeśli nie, pojawi się komunikat „nazwa hosta: nazwa lub usługa nieznana”.
Vebjorn Ljosa,

39
hostname -ijest równoważną krótką formą
Paul Evans

75
Czasami po prostu zwróci 127.0.0.1. Jeśli to możliwe, lepiej użyj nazwy hosta -I zgodnie z zaleceniami podręcznika (Ubuntu): "--ip-address Wyświetla adres (adresy) sieciowe nazwy hosta. Pamiętaj, że działa to tylko wtedy, gdy nazwa hosta może zostać rozwiązana. Unikaj używania ta opcja; zamiast tego użyj nazwy hosta - all-ip-address. ”
jrierab

1
Nie działa również w systemie Linux, a przynajmniej nie hostnamew GNU Coreutils w wersji 8.26.
ack

5
Na moim komputerze hostname -idaje tylko lokalny adres IP, a hostname -Iwszystkie pozostałe adresy IP
Alexis Paques,

62

w systemie Linux

hostname -I

na macOS

ipconfig getifaddr en0

hostname -Imoże zwrócić wiele adresów w niewiarygodnej kolejności (patrz strona hostnamepodręcznika ), ale dla mnie to po prostu zwraca 192.168.1.X, czego właśnie chciałeś.


1
dla mnie było hostname -iz niższym I.
Paul Woitaschek

2
@PaulWoitaschek manpage za małymi -iflaga mówi w ten sposób: Avoid using this option; use hostname -I instead.
Boris

@ Boris, jeśli używasz czegoś w rodzaju kontenera dokującego z systemem Alpine (a zatem BusyBox), akceptuje tylko flagę małych liter -i
bayetovsky

40

Rozwiązanie

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

Wyjaśnienie

Poprawny sposób do informacji o sieci zapytania jest za pomocą ip:

  • -o wyjście jednoliniowe
  • route get to uzyskać aktualną trasę jądra do miejsca docelowego
  • 8.8.8.8 Google IP, ale można użyć prawdziwego adresu IP, który chcesz osiągnąć

np. ipwyjście:

8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \   cache

Aby wyodrębnić srcip, sedjest najlepszym i najbardziej kompatybilnym z obsługą wyrażeń regularnych:

  • -n brak danych wyjściowych domyślnie
  • 's/pattern/replacement/p' dopasuj tylko wzór i zamień druk
  • .*src \([0-9.]\+\).* dopasuj adres IP src używany przez jądro, aby osiągnąć 8.8.8.8

np. końcowy wynik:

192.168.8.16

Inne odpowiedzi

Myślę, że żadna z powyższych odpowiedzi nie jest dla mnie wystarczająco dobra, ponieważ nie działają one na najnowszej maszynie (Gentoo 2018).

Problemy znalezione w poprzednich odpowiedziach:

  • użycie kolumny pozycyjnej w danych wyjściowych polecenia;
  • których użycie ifconfigjest przestarzałe i - na przykład - nie podaje wielu adresów IP;
  • wykorzystanie awkdo prostego zadania, które sed lepiej sobie poradzi;
  • ip route get 1 jest niejasne i faktycznie jest pseudonimem dla ip route get to 1.0.0.0
  • użycie hostnamepolecenia, które nie mają -Iopcji we wszystkich urządzeniach i które zwracają się 127.0.0.1w moim przypadku.

34

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

Dla silniejszej konfiguracji, z wieloma interfejsami i wieloma adresami IP skonfigurowanymi na każdym interfejsie, napisałem czysty skrypt bash (nie oparty na 127.0.0.1) w celu znalezienia poprawnego interfejsu i adresu IP, na podstawie default route. Publikuję ten skrypt na samym dole tej odpowiedzi.

Wprowadzenie

Jak oba Os zainstalowana domyślnie, jest wskazówka bash dla komputerów Mac i Linux:

Problemowi ustawień regionalnych zapobiega się poprzez użycie 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

Umieszczenie tego w funkcji:

Minimalny:

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)
}

Proste użycie:

getMyIP
192.168.1.37

Fantazyjne porządki:

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
}

Stosowanie:

getMyIP
192.168.1.37

lub z uruchomioną tą samą funkcją, ale z argumentem:

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

Nota: Bez argumentu ta funkcja generuje na STDOUT, adres IP i znak nowej linii , z argumentem nic nie jest drukowane, ale tworzona jest zmienna o nazwie jako argument i zawiera adres IP bez znaku nowego wiersza .

Nota2: Zostało to przetestowane na Debianie, LaCie zhakowała nas i MaxOs. Jeśli to nie zadziała w twoim środowisku, będę bardzo zainteresowany informacjami zwrotnymi!

Starsza wersja tej odpowiedzi

(Nie usunięty, ponieważ oparty na sed, nie bash.)

Ostrzeżenie: istnieje problem z ustawieniami regionalnymi!

Szybki i mały:

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

Eksplodował (też działa;)

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

Edytować:

W jaki sposób! Wygląda na to, że nie działa w systemie Mac OS ...

Ok, wydaje się, że działa to tak samo w systemie Mac OS, jak w moim systemie 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; }')

podzielony:

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;
        }')

Mój skrypt (styczeń 2018 r.):

Skrypt ten najpierw znajdzie domyślną trasę i interfejs , a następnie wyszuka lokalną sieć IP dopasowującą bramę i zapełni zmienne. Ostatnie dwa wiersze po prostu drukują, coś w stylu:

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

lub

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

Cóż, oto:

#!/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

1
@sorin: tak, to działa teraz z ifconfig. (jak sbinnie ma na mojej $PATHpełnej ścieżce, należy podać, ale ta sama ścieżka istnieje również w MacOS. :-)
F. Hauri 10.12.

1
@sorin wypróbuj to, timeaby wybrać, którego chcesz używać tak długo ...
F. Hauri

szybkie i małe rozwiązanie było najlepszym rozwiązaniem. Nowsze rozwiązania powodują błędy składniowe. Kompatybilność jest zawsze plusem. Dziękuję Ci.
m3nda

29

Dotyczy tylko niektórych wersji Ubuntu. Chociaż może ci to tylko powiedzieć 127.0.0.1:

hostname  -i

lub

hostname -I

czy to działa w każdym przypadku?
AloneInTheDark

6
Nie. - może ci tylko powiedzieć 127.0.0.1.
SvenDowideit

nazwa hosta -I działa na ubuntu.
Borzh

1
$ hostname --ip-addresspo prostu daje mi 127.0.0.1Arch Arch
kristianlm

1
użyj nazwy hosta -I lub nazwy hosta --all-ip-address
Aydin K.

24

Możesz również uzyskać adres IP w wersji 4 adresu eth0, używając tego polecenia w systemie Linux

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

Wyjście będzie takie

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

Najlepsza odpowiedź dla mnie! Dzięki @Sathish! ;-)
Samuel Phan,

1
Zgadzam się, to najczystsza metoda na uzyskanie IPv4 eth0.
Chris Mendez,

Zakłada się, że eth0, który nie jest aktualną strategią nazewnictwa i nigdy nie był gwarantowany, że będzie podstawowym interfejsem.
rfay

Jest to najbardziej elegancka metoda, jeśli znasz interfejs. Idealny, jeśli twój system ma wiele interfejsów, ale interesuje Cię tylko jeden.
lepe

14

Działa to w systemach Linux i OSX

Spowoduje to powiązanie interfejsu z domyślną trasą

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;}'`

Korzystając z interfejsu odkrytego powyżej, uzyskaj adres 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 Wersja 14.4.0: Czw 28 maja 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 czw. Wrz 3 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU / Linux

echo $NET_IF

eth0

echo $NET_IP

192.168.46.10


Pomimo wszystkich odpowiedzi na to pytanie, to wydaje się być jedyną, która jest prawie tak naprawdę prawidłowa. Po prostu potrzebuje znaku | head -1na końcu pierwszego wiersza, aby uzyskać domyślny interfejs, a reszta jest dobra.
Endareth

12

Korzystanie z niektórych innych metod Możesz wprowadzić konflikt, w którym w systemie jest zdefiniowanych wiele adresów IP. Ta linia zawsze domyślnie używa adresu IP.

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

Nie powiedzie się, jeśli nie ma domyślnej trasy (ale dobry pomysł)
FractalSpace

Fajnie ... Załóżmy, że zadziała, nawet jeśli nie masz internetu?
Boris Churzin,

8

Wyciągam mój komentarz do tej odpowiedzi:

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

Opiera się na odpowiedzi @CollinAnderson, która nie zadziałała w moim przypadku.


8
ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}'

1
Jeśli chcesz zrobić z tego bashalias:alias myip="ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print \$2}'"
Sam Houston

Dobrze. Ale początkowo pytanie dotyczyło polecenia. Właśnie opublikowałem stosownie. Twoje zdrowie!
Faizan Noor

6

Najkrótszy sposób na uzyskanie lokalnego adresu IPv4 w systemie Linux:

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

5
Zły. Strona podręcznika informuje, że nie należy przyjmować żadnych założeń dotyczących kolejności danych wyjściowych.
Matt

Działa świetnie w moich trywialnych przypadkach użycia - nie dbam o to, czy jest szybki i brudny! Świetny!
Nicolai Weitkemper,

6

Zakładając, że potrzebujesz podstawowego publicznego adresu IP takiego, jaki widzi z reszty świata, wypróbuj dowolne z tych:

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

6

Muszę dodać do odpowiedzi Collina Andersona, że ​​ta metoda bierze również pod uwagę, jeśli masz dwa interfejsy i oba są wyświetlane jako aktywne.

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

Pracowałem nad aplikacją z Raspberry Pi i potrzebowałem adresu IP, który był faktycznie używany, nie tylko czy był włączony czy nie. Większość pozostałych odpowiedzi zwróci oba adresy IP, co niekoniecznie jest pomocne - tak czy inaczej w moim scenariuszu.


5

Podstawowy interfejs sieciowy 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

5

Znajduje adres IP tego komputera w sieci, która jest bramą domyślną (na przykład wyklucza wszystkie sieci wirtualne, mosty dokerów) np. bramka internetowa, bramka wifi, ethernet

ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'

Działa w systemie Linux.

Test:

  ~ 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

Miły! Programowanie Taco Bell w najlepszym wydaniu - dzięki za to.
Stevie Howard,

3
ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||'

3

Kolejna ifconfigodmiana, która działa zarówno w systemie Linux, jak i OSX:

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

1
jedna mała odmiana:ifconfig | grep '\<inet\>' | cut -d ' ' -f2 | grep -v '127.0.0.1'
jpbochi,

Dlaczego połowa z tych odpowiedzi w ogóle nie działa dla mnie?
SurpriseDog

3

Przejrzałem wiele linków (StackExchange, AskUbuntu, StackOverflow itp.) I podjąłem decyzję o połączeniu wszystkich najlepszych rozwiązań w jednym skrypcie powłoki.

Moim zdaniem te dwa QA są najlepiej widoczne:

Jak mogę uzyskać mój zewnętrzny adres IP w skrypcie powłoki? https://unix.stackexchange.com/q/22615

Jak mogę znaleźć mój wewnętrzny adres IP? https://askubuntu.com/a/604691

Oto moje rozwiązanie oparte na kilku pomysłach rsp udostępnionych w jego repozytorium ( https://github.com/rsp/scripts/ ).

Niektórzy z was mogliby powiedzieć, że ten skrypt jest niezwykle ogromny jak na tak proste zadanie, ale chciałbym, aby korzystanie z niego było jak najbardziej łatwe i elastyczne. Obsługuje prosty plik konfiguracyjny umożliwiający przedefiniowanie wartości domyślnych.

Został pomyślnie przetestowany pod Cygwin, MINGW i Linux (Red Hat).

Pokaż wewnętrzny adres IP

myip -i

Pokaż zewnętrzny adres IP

myip -e

Kod źródłowy, również dostępny pod linkiem: https://github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip . Przykład pliku konfiguracyjnego znajduje się obok głównego skryptu.

#!/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

3

Używam tylko nazw interfejsów sieciowych , moim niestandardowym poleceniem jest

[[ $(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' 

w moim własnym zeszycie

[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 ~]$

ale jeśli interfejs sieciowy jest właścicielem co najmniej jednego adresu IP, pokaże, że wszystkie adresy IP należą do niego

na przykład

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 ~]#

Wygląda na to, że polecenie ip route get 1 | awk '{print $NF;exit}'dostarczone przez link jest dokładniejsze, a ponadto krótsze.


2

Nie jestem pewien, czy to działa we wszystkich systemach operacyjnych, wypróbuj to.

ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}'

Nie działa w CentOS 7.0
Benoit Blanchon

@BenoitBlanchon Następnie skorzystaj z tego ip route get 1 | awk '{print $NF;exit}'. Powinien działać na większości systemów.
Jotne

Rzeczywiście ip route get 1 | awk '{print $NF;exit}'działa
Benoit Blanchon

2

Na wszystko jest pakiet węzłów. Jest wieloplatformowy i łatwy w użyciu.

$ npm install --global internal-ip-cli

$ internal-ip
fe80::1

$ internal-ip --ipv4
192.168.0.3

Jest to kontrowersyjne podejście, ale stosowanie npm do oprzyrządowania staje się coraz bardziej popularne, czy mu się to podoba, czy nie.


1

Jeśli znasz interfejs sieciowy (eth0, wlan, tun0 itp.):

ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2


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]*' 

1

Działa na komputerach Mac, Linux i wewnątrz kontenerów Docker:

$ 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 '{print1 USD; wyjście}')

Działa również Makefilejako:

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}')}


Mac nie działa: hostname --ip-address=> hostname: illegal option -- -na macOS Sierra
JL Peyret

1

W przypadku Linuksa potrzebne jest to polecenie:

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

wpisz to w swojej powłoce, a po prostu poznasz swój ip.


Nie. To nie działa.
FractalSpace


1

Jeśli masz npmi nodezainstalowałeś:npm install -g ip && node -e "const ip = require('ip'); console.log(ip.address())"

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.