Wie erhalte ich die primäre IP-Adresse des lokalen Computers unter Linux und OS X? [geschlossen]

338

Ich suche nach einer Befehlszeilenlösung, die mir die primäre (erste) IP-Adresse des lokalen Hosts außer 127.0.0.1 zurückgibt

Die Lösung sollte mindestens für Linux (Debian und RedHat) und OS X 10.7+ funktionieren

Mir ist bekannt, dass dies ifconfigauf beiden verfügbar ist, aber die Ausgabe zwischen diesen Plattformen ist nicht so konsistent.

Sorin
quelle
2
Möchten Sie nur die lokale Netzwerk-IP Ihres Computers? dh 192.168.0.12
Chris Seymour
Ja, die lokale IP, zuerst, da sie mehr als eine haben kann, aber ich könnte sogar mit einer Liste leben. Im Moment bin ich froh, nur IPv4-Adressen zu unterstützen und IPv6 zu ignorieren, da ich nur einen Hash generieren möchte.
Sorin
2
Wie definieren Sie "primär"? Wenn Sie denken, "die IP-Adresse befindet sich im selben Subnetz wie meine Standardroute", müssen Sie ein wenig dafür programmieren. Was aber, wenn der Computer keine Standardroute hat, aber dennoch> 1 IP-Adressen hat?
Ghoti
4
Versuchen Sie es curl -4 ifconfig.co. Es wird mit Ihrer externen IP4-Adresse antworten.
Asmaier

Antworten:

475

Verwenden Sie grepdiese Option, um die IP-Adresse zu filtern von ifconfig:

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

Oder mit sed:

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

Wenn Sie nur an bestimmten Schnittstellen interessiert sind, wlan0, eth0 usw., dann:

ifconfig wlan0 | ...

Sie können den Befehl in Ihrem Alias ​​verwenden .bashrc, um einen eigenen Befehl zu erstellen, der beispielsweise aufgerufen wird myip.

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

Ein viel einfacherer Weg ist hostname -I( hostname -ifür ältere Versionen von, hostnameaber siehe Kommentare). Dies ist jedoch nur unter Linux möglich.

Chris Seymour
quelle
5
Beachten Sie auch, dass sed in OSX die -EOption für Extended RE verwendet, nicht die -rOption im GNU-Stil .
Ghoti
1
Interessant; Ich wusste nicht, dass GNU sed unterstützt -E. Neuere Versionen von FreeBSD haben die -rOption als Alias hinzugefügt -E, um die Portabilität von Skripten zu vereinfachen. Das Update wurde jedoch noch nicht auf OSX übertragen. Zuletzt habe ich überprüft, dass immer noch eine Version von sed aus einer FreeBSD-Version von vor einigen Jahren verwendet wird. Ich bin mir nicht sicher, welcher genau, da OSX im Laufe der Jahre einige Male FreeBSD-Quellcode übernommen hat. Ich glaube , dass die Verwendung von -Egedacht war vergleichbar zu sein grep‚s - -EOption. Keine Ahnung, warum sich GNU-Leute -rstattdessen dafür entschieden haben .
Ghoti
1
@ghoti Ich habe die Antwort geändert, um -Edie Portabilität zu gewährleisten. Sie würden denken, dass dies --helpund die man pagesAktualisierung erfolgen würden. Es hat mich früher in einer anderen Frage mit-E
Chris Seymour
1
Ich habe ein Problem gefunden, obwohl dies unter OS X funktioniert, gibt es mehr als eine IP zurück, eine Liste von IPs. Es scheint, dass der erste der richtige ist, aber dennoch würde dies meine Logik brechen. Siehe gist.github.com/ssbarnea/31b9dcb0f8fd528b958c - es werden auch die vnic zurückgegeben, die aktiv sind, aber von Parallelen verwendet werden.
Sorin
13
OSX: ipconfig getifaddr en0
parleer
232

Das Folgende funktioniert unter Linux, aber nicht unter OSX.

Dies hängt überhaupt nicht von DNS ab und funktioniert auch dann, wenn /etc/hostses nicht richtig eingestellt ist ( 1Abkürzung für 1.0.0.0):

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

oder Vermeiden awkund Verwenden des öffentlichen DNS von Google unter 8.8.8.8:

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

Ein weniger zuverlässiger Weg: (siehe Kommentar unten)

hostname -I | cut -d' ' -f1
Collin Anderson
quelle
8
Die Methode, mit der die erste von der erzeugte Adresse abgerufen wird, hostname -Iist unzuverlässig, da (laut Dokumentation) keine Annahmen über die Reihenfolge der Adressen getroffen werden können. Es kann sich also durchaus um ein internes Netzwerk handeln (wie das Netzwerk, in dem virtuelle Maschinen leben). Die andere Methode scheint gut zu sein.
Adam Ryczkowski
3
Dies sollte die akzeptierte Antwort sein, da RHEL 7 ifconfig nicht mehr enthält.
Andrew
10
Für mich ip route get 1 | awk '{print $(NF-2);exit}'funktioniert es, wenn ich an das Outptut angehängt werde
Hritik
13
DIESES (das erste) IST DIE EINZIGE RICHTIGE LÖSUNG . Es ist wichtig , die IP speziell von der Schnittstelle zu lesen, die der Standardroute zugeordnet ist. Andernfalls erhalten Sie höchstwahrscheinlich eine wertlose interne Adresse.
Jan Hudec
12
es hat bei mir nicht funktioniert, aber es war geschlossen genug:ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
estani
230

Für Linux-Computer (nicht OS X):

hostname --ip-address
ACyclisch
quelle
10
Das funktioniert nur, wenn der Name in DNS ist. Wenn nicht, erhalten Sie die Meldung "Hostname: Name oder Dienst nicht bekannt".
Vebjorn Ljosa
39
hostname -iist die entsprechende Kurzform
Paul Evans
75
Dies gibt manchmal einfach 127.0.0.1 zurück. Wenn verfügbar, verwenden Sie besser den Hostnamen -I, wie im Handbuch (Ubuntu) empfohlen: "--ip-address Zeigt die Netzwerkadresse (n) des Hostnamens an. Beachten Sie, dass dies nur funktioniert, wenn der Hostname aufgelöst werden kann. Vermeiden Sie die Verwendung diese Option; verwenden Sie stattdessen den Hostnamen --all-ip-address. "
Jrierab
1
Es funktioniert auch nicht unter Linux, zumindest nicht mit hostnameGNU Coreutils Version 8.26.
Bestätigen Sie den
5
Auf meinem Computer hostname -igibt nur die lokale IP, während hostname -Ialle anderen IPs
Alexis Paques
62

unter Linux

hostname -I

unter macOS

ipconfig getifaddr en0

hostname -Imehrere Adressen in einer unzuverlässigen Ordnung zurückkehren kann (siehe die hostnameMan - Page ), aber für mich ist es gerade Rückkehr 192.168.1.X, das ist das, was Sie wollten.

Boris
quelle
1
für mich war es hostname -imit einem niedrigeren I.
Paul Woitaschek
2
@PaulWoitaschek Die Manpage für die Kleinbuchstaben- -iFlagge sagt dies : Avoid using this option; use hostname -I instead.
Boris
@ Boris, wenn Sie in so etwas wie einem Docker-Container laufen, der Alpine (und damit BusyBox)
ausführt,
40

Lösung

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

Erläuterung

Die richtige Methode zum Abfragen von Netzwerkinformationen ist ip:

  • -o einzeiliger Ausgang
  • route get to Holen Sie sich die tatsächliche Kernel-Route zu einem Ziel
  • 8.8.8.8 Google IP, kann aber die echte IP verwenden, die Sie erreichen möchten

zB ipAusgabe:

8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \   cache

Um die srcIP zu extrahieren , sedist die hellste und am besten mit der Regex-Unterstützung kompatibel:

  • -n Standardmäßig keine Ausgabe
  • 's/pattern/replacement/p' Nur Muster und Druck ersetzen
  • .*src \([0-9.]\+\).* stimmen mit der vom Kernel verwendeten src-IP überein, um zu erreichen 8.8.8.8

zB endgültige Ausgabe:

192.168.8.16

Andere Antwort

Ich denke, keine der vorhergehenden Antworten ist gut genug für mich, da sie in einer neueren Maschine nicht funktionieren (Gentoo 2018).

Probleme, die ich mit vorhergehenden Antworten gefunden habe:

  • Verwendung der Positionsspalte in der Befehlsausgabe;
  • deren Verwendung ifconfigveraltet ist und beispielsweise keine mehrfachen IPs auflistet;
  • Verwendung von awkfür eine einfache Aufgabe, die sed besser bewältigen kann;
  • ip route get 1 ist unklar und ist eigentlich ein Alias ​​für ip route get to 1.0.0.0
  • Verwendung eines hostnameBefehls, der nicht -Iin allen Appliances eine Option hat und 127.0.0.1in meinem Fall zurückgibt.
giosh94mhz
quelle
34

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

Für eine stärkere Konfiguration mit vielen Schnittstellen und vielen IP-Adressen, die auf jeder Schnittstelle konfiguriert sind, habe ich ein reines Bash- Skript (nicht basierend auf 127.0.0.1) geschrieben, um die richtige Schnittstelle und IP basierend auf zu finden default route. Ich poste dieses Skript ganz unten in dieser Antwort.

Intro

Wie beide Os haben Standardmäßig installiert, gibt es einen Bash-Tipp für Mac und Linux:

Das Problem mit dem Gebietsschema wird durch Folgendes verhindert 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

Dies in eine Funktion umsetzen:

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

Einfache Verwendung:

getMyIP
192.168.1.37

Lust auf Ordnung:

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
}

Verwendungszweck:

getMyIP
192.168.1.37

oder mit derselben Funktion, jedoch mit einem Argument:

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

Anmerkung: Ohne Argument wird diese Funktion auf STDOUT, der IP und einer Newline ausgegeben , mit einem Argument wird nichts gedruckt, aber eine als Argument bezeichnete Variable wird erstellt und enthält IP ohne Newline .

Nota2: Dies wurde auf Debian getestet, LaCie hackte nas und MaxOs. Wenn dies unter Ihrer Umgebung nicht funktioniert, bin ich sehr an Rückmeldungen interessiert!

Ältere Version dieser Antwort

(Nicht gelöscht, weil basierend auf sed, nicht bash.)

Warnung: Es gibt ein Problem mit Gebietsschemas!

Schnell und klein:

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

Explodiert (Arbeit auch;)

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

Bearbeiten:

Wie! Dies scheint unter Mac OS nicht zu funktionieren ...

Ok, dies scheint unter Mac OS genauso zu funktionieren wie unter 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; }')

aufgeteilt:

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

Mein Drehbuch (Januar 2018):

Dieses Skript findet zuerst Ihre Standardroute und -schnittstelle , für die es verwendet wird, und sucht dann nach dem lokalen IP-passenden Netzwerk des Gateways und füllt Variablen. Die letzten beiden Zeilen werden nur gedruckt, so etwas wie:

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

oder

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

Nun, da ist es:

#!/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
F. Hauri
quelle
1
@sorin: ja, das funktioniert jetzt mit ifconfig. (wie sbinnicht auf meinem $PATHvollständigen Pfad angegeben werden muss, aber der gleiche Pfad existiert auch unter MacOS .:-)
F. Hauri
1
@ Sorin versuchen Sie dies mit, timeum auszuwählen, welche Sie so lange verwenden würden ...
F. Hauri
Die schnelle und kleine Lösung war der beste Ansatz. Neuere Lösungen geben mir Syntaxfehler. Kompatibilität ist immer ein Plus. Vielen Dank.
m3nda
29

Spezifisch nur für bestimmte Builds von Ubuntu. Obwohl es Ihnen vielleicht nur sagt 127.0.0.1:

hostname  -i

oder

hostname -I
user3173508
quelle
funktioniert das in jedem fall?
AloneInTheDark
6
Nein. - Es kann Ihnen nur 127.0.0.1 sagen.
SvenDowideit
Hostname -Ich arbeite mit Ubuntu.
Borzh
1
$ hostname --ip-addressgibt mir nur 127.0.0.1auf Arch Linux
kristianlm
1
Verwenden Sie den Hostnamen -I oder den Hostnamen --all-ip-address
Aydin K.
24

Sie können die IP-Adresse 4 von eth0 auch mit diesem Befehl unter Linux abrufen

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

Die Ausgabe wird so sein

[root@localhost Sathish]# /sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}'
192.168.1.22
Sathish
quelle
Die beste Antwort auf mich! Danke @Sathish! ;-)
Samuel Phan
1
Ich stimme zu, dies ist die sauberste Methode, um IPv4 von eth0 zu erhalten.
Chris Mendez
Dies setzt eth0 voraus, was keine aktuelle Namensstrategie ist und niemals als primäre Schnittstelle garantiert wurde.
Rfay
Dies ist die eleganteste Methode, wenn Sie die Benutzeroberfläche kennen. Ideal, wenn Ihr System über mehrere Schnittstellen verfügt, Sie jedoch nur an einer bestimmten interessiert sind.
Lepe
14

Dies funktioniert unter Linux und OSX

Dadurch wird die der Standardroute zugeordnete Schnittstelle abgerufen

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

Rufen Sie über die oben beschriebene Schnittstelle die IP-Adresse ab.

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 Version 14.4.0: Do 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

CentOS Linux

uname -a

Linux dev-cil.medfx.local 2.6.18-164.el5xen 1 SMP Do 3. September 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU / Linux

echo $NET_IF

eth0

echo $NET_IP

192.168.46.10

Colin Fletcher
quelle
Trotz aller Antworten auf diese Frage scheint diese die einzige zu sein, die der tatsächlichen Richtigkeit nahe kommt. Benötigt nur ein | head -1am Ende der ersten Zeile, um die Standardschnittstelle zu erhalten, und der Rest ist gut.
Endareth
12

Verwenden einiger anderer Methoden Sie können einen Konflikt eingeben, bei dem mehrere IP-Adressen auf dem System definiert sind. Diese Zeile erhält standardmäßig immer die verwendete IP-Adresse.

ip route get 8.8.8.8 | head -1 | awk '{print $7}'
Kjeld Flarup
quelle
Es wird fehlschlagen, wenn es keine Standardroute gibt (aber gute Idee)
FractalSpace
Schön ... Angenommen, Sie arbeiten, auch wenn Sie kein Internet haben?
Boris Churzin
8

Ich extrahiere meinen Kommentar zu dieser Antwort:

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

Es basiert auf der Antwort von @CollinAnderson, die in meinem Fall nicht funktioniert hat.

estani
quelle
8
ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}'
Faizan Noor
quelle
1
Wenn Sie dies zu einem bashAlias machen alias myip="ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print \$2}'"
Sam Houston
Recht. Aber die Frage war zunächst über den Befehl. Also habe ich gerade relevant gepostet. Prost!
Faizan Noor
6

Der kürzeste Weg, um Ihre lokale IPv4-Adresse auf Ihrem Linux-System zu erhalten:

hostname -I | awk '{print $1}'
Harry
quelle
5
Schlecht. Die Manpage weist Sie ausdrücklich an, keine Annahmen über die Reihenfolge der Ausgabe zu treffen.
Matt
Funktioniert hervorragend für meine trivialen Anwendungsfälle - es ist mir egal, ob es schnell und schmutzig ist! Großartig!
Nicolai Weitkemper
6

Angenommen, Sie benötigen Ihre primäre öffentliche IP-Adresse, wie sie vom Rest der Welt aus gesehen wird, versuchen Sie eine der folgenden Möglichkeiten:

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

Ich muss Collin Andersons Antwort hinzufügen, dass diese Methode auch berücksichtigt, wenn Sie zwei Schnittstellen haben und beide als oben angezeigt werden.

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

Ich habe an einer Anwendung mit Raspberry Pi's gearbeitet und brauchte die IP-Adresse, die tatsächlich verwendet wurde, nicht nur, ob sie aktiv war oder nicht. Die meisten anderen Antworten geben beide IP-Adressen zurück, was nicht unbedingt hilfreich ist - für mein Szenario jedenfalls.

c7borg
quelle
5

IP der primären Netzwerkschnittstelle

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
Kaspars
quelle
5

Findet eine IP-Adresse dieses Computers in einem Netzwerk, das ein Standard-Gateway ist (z. B. schließt alle virtuellen Netzwerke, Docker-Bridges aus), z. Internet-Gateway, WLAN-Gateway, Ethernet

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

Funktioniert unter Linux.

Prüfung:

  ~ 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
Krzysztof Wesołowski
quelle
Nett! Taco Bell Programmierung vom Feinsten - danke dafür.
Stevie Howard
3
ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||'
rbolante
quelle
3

Eine weitere ifconfigVariante, die sowohl unter Linux als auch unter OSX funktioniert:

ifconfig | grep "inet " | cut -f2 -d' '
ccpizza
quelle
1
eine kleine Variation:ifconfig | grep '\<inet\>' | cut -d ' ' -f2 | grep -v '127.0.0.1'
jpbochi
Warum funktioniert die Hälfte dieser Antworten bei mir überhaupt nicht?
SurpriseDog
3

Ich ging viele Links durch (StackExchange, AskUbuntu, StackOverflow usw.) und kam zu der Entscheidung, die besten Lösungen in einem Shell-Skript zu kombinieren.

Meiner Meinung nach sind diese beiden QAs die besten:

Wie kann ich meine externe IP-Adresse in einem Shell-Skript erhalten? https://unix.stackexchange.com/q/22615

Wie finde ich meine interne IP-Adresse? https://askubuntu.com/a/604691

Hier ist meine Lösung, die auf einigen Ideen von rsp basiert, die in seinem Repository ( https://github.com/rsp/scripts/) geteilt wurden. ) geteilt wurden.

Einige von Ihnen könnten sagen, dass dieses Skript für so einfache Aufgaben extrem umfangreich ist, aber ich möchte es so einfach und flexibel wie möglich gestalten. Es unterstützt einfache Konfigurationsdateien, mit denen die Standardwerte neu definiert werden können.

Es wurde erfolgreich unter Cygwin, MINGW und Linux (Red Hat) getestet.

Interne IP-Adresse anzeigen

myip -i

Externe IP-Adresse anzeigen

myip -e

Quellcode, auch über den Link verfügbar: https://github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip . Ein Beispiel für eine Konfigurationsdatei befindet sich neben dem Hauptskript.

#!/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
jsxt
quelle
3

Ich verwende nur Netzwerkschnittstellennamen , mein benutzerdefinierter Befehl lautet

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

in meinem eigenen Notizbuch

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

Wenn die Netzwerkschnittstelle jedoch mindestens eine IP-Adresse besitzt, wird angezeigt, dass alle IP-Adressen dazu gehören

zum Beispiel

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

Es scheint, dass ip route get 1 | awk '{print $NF;exit}'der von link bereitgestellte Befehl genauer ist, außerdem kürzer.

Gemeinschaft
quelle
2

Nicht sicher, ob dies in allen Betriebssystemen funktioniert, probieren Sie es aus.

ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}'
Jotne
quelle
Funktioniert nicht unter CentOS 7.0
Benoit Blanchon
@ BenoitBlanchon Dann benutze dies ip route get 1 | awk '{print $NF;exit}'. Sollte auf den meisten Systemen funktionieren.
Jotne
In der Tat ip route get 1 | awk '{print $NF;exit}'funktioniert
Benoit Blanchon
2

Es gibt ein Knotenpaket für alles. Es ist plattformübergreifend und einfach zu bedienen.

$ npm install --global internal-ip-cli

$ internal-ip
fe80::1

$ internal-ip --ipv4
192.168.0.3

Dies ist ein kontroverser Ansatz, aber die Verwendung von npm für Werkzeuge wird immer beliebter, ob es Ihnen gefällt oder nicht.

Dennis
quelle
1

Wenn Sie die Netzwerkschnittstelle kennen (eth0, wlan, tun0 usw.):

ifconfig eth0 | grep addr: | awk '{ print $2 }' | cut -d: -f2
Droidgren
quelle
1
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
user2802053
quelle
funktioniert nicht unter macOS 10.12.6
Antoine F.
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]*' 
AlanG
quelle
1

Funktioniert unter Mac, Linux und in Docker Containern:

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

Funktioniert auch Makefileals:

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

peleteiro
quelle
Mac funktioniert nicht: hostname --ip-address=> hostname: illegal option -- -unter macOS Sierra
JL Peyret
1

Für Linux benötigen Sie den folgenden Befehl:

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

Geben Sie dies in Ihre Shell ein und Sie werden einfach Ihre IP kennen.

Statham
quelle
Nein es geht nicht.
FractalSpace
1

Dies ist leichter zu lesen: ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr:

Cory Thorson
quelle
funktioniert nicht unter macOS 10.12.6
Antoine F.
1

Wenn Sie haben npmund nodeinstalliert haben:npm install -g ip && node -e "const ip = require('ip'); console.log(ip.address())"

Antoine F.
quelle