Które polecenie terminala ma uzyskać tylko adres IP i nic więcej?

118

Próbuję użyć tylko adresu IP (inet) jako parametru w skrypcie, który napisałem.

Czy w terminalu unix można łatwo uzyskać tylko adres IP, zamiast go przeglądać ifconfig?

Mason
źródło
Tak, lub inny unikalny identyfikator maszyny, jak przypuszczam.
Mason
1
otrzymujesz niepoprawną opcję na nazwie hosta -i?
Ken,
4
nazwa hosta nie jest tak wiarygodna jak ifconfig
joel
2
joel ma rację, szczególnie ty, kiedy mówisz o MAC OS, a potem Ubuntu
zackaryka
2
Przeglądając poniższe odpowiedzi, należy pamiętać, że dane wyjściowe ip -o addresssą znacznie łatwiejsze w użyciu niż dane wyjściowe ip address.
jlh

Odpowiedzi:

177

Możesz napisać skrypt, który zwraca tylko adres IP, taki jak:

/sbin/ifconfig eth0 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}'

Dla Maca:

ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d\  -f2

Lub dla systemu Linux

hostname -i | awk '{print $3}' # Ubuntu 

hostname -i # Debian
Księga Zeusa
źródło
4
hostname -ina moim powraca:::1 127.0.1.1 192.168.1.100
Book Of Zeus
1
W Debianie mam tylko jeden adres IP. Więc używanie hostnamenie jest przenośne.
Timofey Stolbov
1
Mówi, że opcje -i i -I są niedozwolonymi opcjami
Mason
3
Podsumowując: pierwsza metoda zależy od adaptera, który nie zawsze jest taki sam. Drugi, dla mnie, pokazuje dwa adresy IP, a dwa ostatnie nie działają na Macu.
Matt,
4
ifconfig jest tutaj przestarzały i zawodny, np. grep nie działa na Debianie 9 (stretch), ponieważ nie wyświetla już „inet addr: 172.17.0.4”, wyświetla tylko „inet 172.17.0.4”. Zamiast tego użyj „ip”, jak opisano na stackoverflow.com/a/26694162/72717 .
jamshid
61

W ten sposób otrzymasz wszystkie interfejsy IPv4, w tym pętlę zwrotną 127.0.0.1:

ip -4 addr | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

To pokaże tylko eth0:

ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

W ten sposób możesz uzyskać adresy IPv6:

ip -6 addr | grep -oP '(?<=inet6\s)[\da-f:]+'

Tylko eth0IPv6:

ip -6 addr show eth0 | grep -oP '(?<=inet6\s)[\da-f:]+'
SAM
źródło
grep -oPNie na BusyBox v1.24.1: nieprawidłową opcję - P
Backup Pro
1
grep nie jest instalowany na prawie każdym konsolecie Docker dla prod. Więc chociaż to wszystko są dobre polecenia, nie będą przydatne na kontenerach :-(
AndyGee
1
Najlepsza odpowiedź w moim konkretnym przypadku. Potrzebujesz -Pprzełącznika dla wyrażeń regularnych Perla, w przeciwnym razie nie możemy użyć (?<=inet\s)tokenu lookbehind . Podobny wynik uzyskasz biegając grep -oe 'inet [0-9\.]\+'albo grep -oe 'inet6 [0-9a-f:]\+'ale w ten sposób nie mogę pozbyć się pierwszego słowa. W man grepraportach SuSE ta -Pflaga jest eksperymentalna.
Jorge Bellon
To najlepsza odpowiedź. ifconfig jest przestarzały od kilku lat w większości systemów operacyjnych.
pozcircuitboy
2
Krótsza wersja drugiej komendy:ip -4 a show eth0 | grep -Po 'inet \K[0-9.]*'
tukusejssirs
41

Ogólnie rzecz biorąc, nigdy nie ma gwarancji, że system będzie miał tylko jeden adres IP, na przykład możesz mieć zarówno połączenie Ethernet, jak i WLAN, a jeśli masz aktywne połączenie VPN, będziesz mieć kolejny adres IP.

Linux

W systemie Linux hostname -Iwyświetli bieżące adresy IP. Poleganie na tym, że zawsze zwraca tylko jeden adres IP, najprawdopodobniej nie zadziała zgodnie z oczekiwaniami w niektórych scenariuszach (np. Łącze VPN działa), więc bardziej niezawodnym sposobem byłoby przekonwertowanie wyniku na tablicę, a następnie zapętlenie elementów:

ips=($(hostname -I))

for ip in "${ips[@]}"
do
    echo $ip
done

OSX

Na OSX, jeśli znasz interfejs , możesz użyć:

~$ ipconfig getifaddr en0
192.168.1.123

który zwróci tylko adres IP.

Lub możesz zapętlić możliwe nazwy interfejsów, zaczynając od sufiksu, np . en:

for NUMBER in $(seq 0 5); do
    ip=`ipconfig getifaddr en$NUMBER`
    if [ -n "$ip" ]; then
        myip="$ip"
        break
    fi
done

echo $myip

Ponadto uzyskanie adresu IP staje się niedeterministyczne w przypadku ustanowienia zarówno połączenia kablowego, jak i Wi-Fi, gdy maszyna ma więcej niż jeden interfejs Ethernet lub gdy obecne są tunele VPN.

Uzyskanie zewnętrznego adresu IP

Jeśli potrzebujesz zewnętrznego adresu IP, możesz wysłać zapytanie do usługi w trybie tekstowym, na przykład curl https://ipecho.net/plainzwróci zewnętrzny adres IP w postaci zwykłego tekstu .

Jeszcze szybszym sposobem uzyskania zewnętrznego adresu IP jest wysłanie zapytania do znanego serwera DNS:

dig @ns1-1.akamaitech.net ANY whoami.akamai.net +short
ccpizza
źródło
jak uzyskać adres IP LAN?
diEcho
17
hostname -I  

To polecenie da ci dokładny adres IP, jaki chcesz w Ubuntu.

Vignajeth
źródło
w porównaniu z liczbą już istniejących (i wysoko ocenionych) odpowiedzi, nie sądzę, aby ta odpowiedź dodała jakąkolwiek wartość ...
Mischa
4
także na
Centos nazwa
1
to faktycznie pomogło mi - zauważone duże „i” było kluczem
ChronoFish
2
To samo robi to doskonale, bez dodatkowych narzędzi i bez potrzeby wywoływania piętnastu plików binarnych z rzędu w celu oczyszczenia wyniku. Dzięki !
Ulrar
11

W najnowszych wersjach Ubuntu ( 14.04 - 16.04 ) to polecenie załatwiło sprawę .

hostname -I | awk '{print $1}'
Da CodeKid
źródło
1
Ze strony podręcznika: "[...] Ta opcja wylicza wszystkie skonfigurowane adresy na wszystkich interfejsach sieciowych. [...] Nie rób żadnych założeń co do kolejności wyjścia". Ostatnie zdanie mówi, że print $1może, ale nie musi, dać prawidłowy wynik.
0 0
7

Jeśli masz ograniczone środowisko, możesz użyć tego polecenia:

ip -4 addr show dev eth0 | grep inet | tr -s " " | cut -d" " -f3 | head -n 1
caglar
źródło
3
Lub nawet:ip -o -4 addr show dev eth0 | cut -d' ' -f7 | cut -d'/' -f1
Jose Alban
Tak masz rację. Ale uważaj, jeśli eth0 ma więcej niż jeden adres IP, to pokazuje je wszystkie.
caglar
bash-4.4 # ip -4 addr show dev eth0 | grep inet | tr -s "" | cut -d "" -f3 | głowa -n 1 172.17.0.3/16 Tak źle z / 16
AndyGee
Dodanie jednej z pętli: ip -4 addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1. Zarówno dla wersji 4, jak i 6:ip addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1
Sumit Murari
Jeśli nazwa interfejsu nie jest znana (lub różni się między platformami), ale szukasz prywatnego adresu IP, zamiast ip -4 addr show eth0 | grep inetwykonać:ip -4 addr show | grep 192
cyberbird
6

Aby uzyskać tylko adres IP w systemie Mac OS X , możesz wpisać następujące polecenie:

ipconfig getifaddr en0
Tukan3
źródło
4

Polecenie ifconfigzostało usunięte i powinieneś go używać ipw systemie Linux.

Zapewnia również ip azakres w tej samej linii co IP, dzięki czemu jest łatwiejszy w użyciu.

To polecenie pokaże ci twój globalny (zewnętrzny) adres IP:

ip a | grep "scope global" | grep -Po '(?<=inet )[\d.]+'

Wszystkie IPv4 (także 127.0.0.1):

ip a | grep "scope" | grep -Po '(?<=inet )[\d.]+'

Wszystkie IPv6 (także :: 1):

ip a | grep "scope" | grep -Po '(?<=inet6 )[\da-z:]+'
Nux
źródło
4

Możemy po prostu użyć tylko 2 poleceń (ifconfig + awk), aby uzyskać tylko adres IP (v4), który chcemy:

W systemie Linux, zakładając uzyskanie adresu IP z eth0interfejsu, uruchom następujące polecenie:

/sbin/ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'

W systemie OSX, zakładając uzyskanie adresu IP z en0interfejsu, uruchom następujące polecenie:

/sbin/ifconfig en0 | awk '/inet /{print $2}'

Aby poznać nasz publiczny / zewnętrzny adres IP, dodaj tę funkcję w ~/.bashrc

whatismyip () {
    curl -s "http://api.duckduckgo.com/?q=ip&format=json" | jq '.Answer' | grep --color=auto -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"
}

Następnie uruchomić, whatismyip

zdk
źródło
4

Aby wydrukować tylko adres IP eth0, bez innego tekstu:

ifconfig eth0 | grep -Po '(?<=inet )[\d.]+'

Aby określić główny interfejs (ponieważ może to nie być „eth0”), użyj:

route | grep ^default | sed "s/.* //"

Powyższe dwie linie można połączyć w jedno polecenie, na przykład:

ifconfig `route | grep ^default | sed "s/.* //"` \
  | grep -Po '(?<=inet )[\d.]+'
personal_cloud
źródło
3

Chciałem czegoś prostego, które działałoby jak alias Bash. Okazało się, że hostname -Idziała najlepiej dla mnie (nazwa hosta v3.15). hostname -iz jakiegoś powodu zwraca adres IP pętli zwrotnej, ale hostname -Ipodaje mi poprawny adres IP dla wlan0 i bez konieczności przesyłania danych potokiem przez grep lub awk. Wadą jest to, że hostname -Iwyświetlają wszystkie adresy IP, jeśli masz więcej niż jeden.

Andy Forceno
źródło
2

To załatwiłoby sprawę na komputerze Mac:

ping $(ifconfig en0 | awk '$1 == "inet" {print $2}')

To rozwiązało się ping 192.168.1.2w mojej maszynie.

Wskazówka dla profesjonalistów : $(...)oznacza uruchomienie wszystkiego, co znajduje się w nawiasach w podpowłoce i zwrócenie tego jako wartości.

Abdellah Alaoui
źródło
2

W man hostnametym jest jeszcze prostszy sposób, który automatycznie wyklucza IP pętli zwrotnej i wyświetla tylko listę rozdzielonych spacjami wszystkich przypisanych do adresów IP hostów:

root@srv:~# hostname --all-ip-addresses
11.12.13.14 192.168.15.19 

root@srv:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
   inet6 ::1/128 scope host 
   valid_lft forever preferred_lft forever
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
  link/void 
  inet 11.12.13.14/32 scope global venet0:0
  inet 192.168.15.19/32 scope global venet0:1
user10101010
źródło
2

Możesz również użyć następującego polecenia:

ip route | grep src

UWAGA: zadziała to tylko wtedy, gdy masz połączenie z Internetem.

Szukaj informacji
źródło
2

Kilka odpowiedzi wydają się być przy użyciu nowszej ippolecenia (zastępczego ifconfig), więc tutaj jest jeden, który używa ip addr, grepi awkpo prostu wydrukować adres IPv4 związany z wlan0interfejsem:

ip addr show wlan0|grep inet|grep -v inet6|awk '{print $2}'|awk '{split($0,a,"/"); print a[1]}'

Chociaż nie jest to najbardziej kompaktowe ani wymyślne rozwiązanie, jest (prawdopodobnie) łatwe do zrozumienia (patrz wyjaśnienie poniżej) i zmodyfikowania do innych celów, takich jak pobranie ostatnich 3 oktetów adresu MAC, takich jak ten:

ip addr show wlan0|grep link/ether|awk '{print $2}'|awk '{split($0,mac,":"); print mac[4] mac[5] mac[6]}'

Objaśnienie: ip addr show wlan0 wyświetla informacje powiązane z wymienionym interfejsem sieciowym wlan0, które powinny być podobne do następującego:

4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether dc:a6:32:04:06:ab brd ff:ff:ff:ff:ff:ff
    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::d340:5e4b:78e0:90f/64 scope link 
       valid_lft forever preferred_lft forever

Następnie grep inetodfiltrowuje wiersze, które nie zawierają „inet” (konfiguracja IPv4 i IPv6) i grep -v inet6odfiltrowuje pozostałe wiersze, które zawierają „inet6”, co powinno dać w wyniku pojedynczy wiersz taki jak ten:

    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0

Na koniec pierwsza awkwyodrębnia pole „172.18.18.1/24”, a druga usuwa skrót maski sieci, pozostawiając tylko adres IPv4.

Myślę też, że warto wspomnieć, że jeśli tworzysz skrypty, często istnieje wiele bogatszych i / lub solidniejszych narzędzi do uzyskiwania tych informacji, których możesz chcieć użyć. Na przykład, jeśli używasz Node.js ipaddr-linux, jeśli używasz Rubiego linux-ip-parser, itd.

Zobacz też /unix/119269/how-to-get-ip-address-using-shell-script

iX3
źródło
1

Użyj następującego polecenia:

/sbin/ifconfig $(netstat -nr | tail -1 | awk '{print $NF}') | awk -F: '/inet /{print $2}' | cut -f1 -d ' '
Jose Martinez Poblete
źródło
1

Oto moja wersja, w której możesz przekazać listę interfejsów uporządkowanych według priorytetu:

getIpFromInterface()
{
    interface=$1
    ifconfig ${interface}  > /dev/null 2>&1 && ifconfig ${interface} | awk -F'inet ' '{ print $2 }' | awk '{ print $1 }' | grep .
}

getCurrentIpAddress(){
    IFLIST=(${@:-${IFLIST[@]}})
    for currentInterface in ${IFLIST[@]}
    do
        IP=$(getIpFromInterface  $currentInterface)
        [[ -z "$IP" ]] && continue
    echo ${IP/*:}
    return
    done
}

IFLIST=(tap0 en1 en0)
getCurrentIpAddress $@

Więc jeśli jestem połączony przez VPN, Wi-Fi i Ethernet, mój adres VPN (na interfejsie tap0) zostanie zwrócony. Skrypt działa zarówno na Linuksie, jak i na OSX i może przyjmować argumenty, jeśli chcesz przesłonić IFLIST

Zauważ, że jeśli chcesz używać IPV6, musisz zamienić „inet” na „inet6”.

MatthieuP
źródło
1

Zawsze potrzebuję tego w najbardziej nieoczekiwanych momentach i bez wątpienia szukam takich wątków w SO. Napisałem więc prosty skrypt do pobierania adresów IPv4 przez netstat, nazwany echoip- możesz go znaleźć tutaj . Bash dla adresów sieciowych wygląda następująco, pobiera również Twój adres publiczny z ipecho.net:

IPV4='\d+(\.\d+){3}'
INTERFACES=`netstat -i | grep -E "$IPV4" | cut -d ' ' -f 1`
INTERFACE_IPS=`netstat -i | grep -oE "$IPV4"`

for i in "${!INTERFACES[@]}"; do
  printf "%s:\t%s\n" "${INTERFACES[$i]}" "${INTERFACE_IPS[$i]}"
done

echoipSkrypt daje wyjście takiego:

$ echoip
public: 26.106.59.169
en0:    10.1.10.2
stites
źródło
1

użyj tego skryptu ifconfig | grep "inet " | grep -v 127.0.0.1|awk 'match($0, /([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/) {print substr($0,RSTART,RLENGTH)}' jednowierszowego : Mac i linux (testowane w systemie Ubuntu) działają.

Huan
źródło
Fajnie, że działa na obu. Dodatkowo możesz zadzwonić za pomocą ifconfig en0lub ifconfig eth1itp., Jeśli znasz interfejs, który chcesz :)
jaygooby
1

Wolę nie używać awki takie w skryptach .. ipma opcję wyprowadzania w JSON.

Jeśli opuścisz, $interfaceotrzymasz wszystkie adresy IP:

ip -json addr show $interface | \
  jq -r '.[] | .addr_info[] | select(.family == "inet") | .local'
Tal Zion
źródło
Podoba mi się sposób, w jaki wynik polecenia w formacie strukturalnym json, takim jak polecenie ip. tutaj jest inny sposób na uzyskanie adresu IP, podobnie jak powyżej bash ip -j addr show eth0 | jp "[0].addr_info[?family== 'inet'].local | [0]"
Jack Liu Shurui
0
ip addr|awk '/eth0/ && /inet/ {gsub(/\/[0-9][0-9]/,""); print $2}'

pokazuje wszystkie twoje adresy IP

Maksyma
źródło
0

Na Redhat 64bit ten problem rozwiązał za mnie.

ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }'
Statham
źródło
lub to: curl ifconfig.me
Statham
0
#!/bin/sh
# Tested on Ubuntu 18.04 and Alpine Linux 
# List IPS of following network interfaces:
# virtual host interfaces
# PCI interfaces
# USB interfaces
# ACPI interfaces
# ETH interfaces
for NETWORK_INTERFACE in $(ls /sys/class/net -al | grep -iE "(/eth[0-9]+$|vif|pci|acpi|usb)" | sed -E "s@.* ([^ ]*) ->.*@\1@"); do 
    IPV4_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet addr[: ]+|inet[: ]+)' | sed -E "s@\s*(inet addr[: ]+|inet[: ]+)([^ ]*) .*@\2@")
    IPV6_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet6 addr[: ]+|inet6[: ]+)' | sed -E "s@\s*(inet6 addr[: ]+|inet6[: ]+)([^ ]*) .*@\2@")
    if [ -n "$IPV4_ADDRESSES" ] || [ -n "$IPV6_ADDRESSES" ]; then
        echo "NETWORK INTERFACE=$NETWORK_INTERFACE"
        for IPV4_ADDRESS in $IPV4_ADDRESSES; do 
            echo "IPV4=$IPV4_ADDRESS"
        done
        for IPV6_ADDRESS in $IPV6_ADDRESSES; do 
            echo "IPV6=$IPV6_ADDRESS"
        done
    fi
done
user11621528
źródło
0

Podczas wyszukiwania zewnętrznego adresu IP na hoście z NAT, wiele odpowiedzi sugeruje użycie metod opartych na HTTP, takich jak ifconfig.menp:

$ curl ifconfig.me/ip

Przez lata widziałem, jak wiele z tych witryn pojawia się i znika, uważam, że ta metoda oparta na DNS jest bardziej niezawodna:

$ dig +short myip.opendns.com @resolver1.opendns.com

Mam ten poręczny alias w moim ~/.bashrc:

alias wip='dig +short myip.opendns.com @resolver1.opendns.com'
htaccess
źródło
0

Te dwa sposoby zadziałały dla mnie:

Aby uzyskać adres IP interfejsu, eth0. Zastąp eth0 w poniższym przykładzie nazwą swojego interfejsu. ifconfig eth0 | grep -w "inet" | tr -s " " | cut -f3 -d" "

Używanie nazwy hosta: To da ci inet, czyli adres IP twojego etosu. używając -Podam ci wartość inet wszystkich interfejsów, gdziekolwiek ta wartość jest obecna.

hostname -i

Milind
źródło
-1
curl ifconfig.co 

Zwraca tylko adres IP twojego systemu.

Prudhvi Raj Mudunuri
źródło
1
Wymaga to działającego połączenia internetowego i zwróci Twój publicznie widoczny adres IP, który może, ale nie musi, być tym, czego chcesz.
jlh
-2

Użyłbym, Hostname -Laby uzyskać tylko adres IP, który ma być używany jako zmienna w skrypcie.

HtmlGifited
źródło
Być może próbowałeś powiedzieć hostname -ilub hostname -I?
jlh
user@linux:~$ Hostname -L -bash: Hostname: command not found user@linux:~$ 1. Kapitał Hjest zły 2. Nie ma takiego-L
Sabrina