วิธีรับที่อยู่ IP หลักของเครื่องในระบบบน Linux และ OS X [ปิด]


339

ฉันกำลังมองหาโซลูชันบรรทัดคำสั่งที่จะส่งคืนที่อยู่ IP หลัก (แรก) ของ localhost นอกเหนือจาก 127.0.0.1

โซลูชันควรทำงานอย่างน้อยสำหรับ Linux (Debian และ RedHat) และ OS X 10.7+

ฉันทราบว่าifconfigมีให้ทั้งสองแบบ แต่ผลลัพธ์ไม่สอดคล้องกันระหว่างแพลตฟอร์มเหล่านี้


2
คุณเพียงแค่ต้องการ IP เครือข่ายท้องถิ่นของเครื่องของคุณ? เช่น 192.168.0.12
Chris Seymour

ใช่ IP ท้องถิ่นก่อนอื่นเพราะสามารถมีได้มากกว่าหนึ่งรายการ แต่ฉันสามารถอยู่ได้แม้จะมีรายการ ในขณะนี้ฉันยินดีที่จะสนับสนุนเฉพาะที่อยู่ IPv4 และไม่สนใจ IPv6 ตามที่ต้องการเพียงเพื่อสร้างแฮช
sorin

2
คุณจะกำหนด "หลัก" ได้อย่างไร หากคุณกำลังคิดว่า "ที่อยู่ IP ที่อยู่ในซับเน็ตเดียวกันกับเส้นทางเริ่มต้นของฉัน" คุณจะต้องโปรแกรมสักเล็กน้อยสำหรับสิ่งนั้น แต่ถ้าเครื่องไม่มีเส้นทางเริ่มต้น แต่ยังมีที่อยู่ IP มากกว่า 1 เครื่อง
ghoti

4
ลองcurl -4 ifconfig.coดู มันจะตอบด้วยที่อยู่ IP4 ภายนอกของคุณ
asmaier

คำตอบ:


475

ใช้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]*).*/\2/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]*).*/\2/p'"

วิธีที่ง่ายกว่ามากคือhostname -I( hostname -iสำหรับรุ่นเก่าhostnameแต่ดูความคิดเห็น) อย่างไรก็ตามนี่เป็น Linux เท่านั้น


5
โปรดทราบว่าใน OSX sed ใช้-Eตัวเลือกสำหรับ Extended RE ไม่ใช่-rตัวเลือกสไตล์ GNU
ghoti

1
ที่น่าสนใจ; ผมไม่ทราบว่า GNU sed -Eสนับสนุน FreeBSD เวอร์ชันล่าสุดได้เพิ่ม-rตัวเลือกเป็นนามแฝง-Eเพื่อความสะดวกในการพกพาสคริปต์ แต่การปรับปรุงยังไม่ได้ถูกนำไปใช้กับ OSX ซึ่งล่าสุดที่ฉันตรวจสอบยังคงใช้รุ่น sed จาก FreeBSD รุ่นไม่กี่ปีที่ผ่านมา ไม่แน่ใจว่าจะใช้อันไหนเพราะ OSX ได้ใช้ซอร์สโค้ด FreeBSD สองสามครั้งในช่วงหลายปีที่ผ่านมา ผมเชื่อว่าการใช้-Eตั้งใจจะเทียบได้กับgrep's -Eตัวเลือก ไม่รู้เลยว่าทำไม GNU folks เลือกใช้-rแทน
ghoti

1
@ghoti ผมเปลี่ยนคำตอบที่จะใช้-Eเพื่อให้แน่ใจว่าการพกพาคุณคิดว่า--helpและman pagesจะได้รับการปรับปรุง .. มันก็ทำให้เกิดความสับสนเล็กน้อยสำหรับฉันก่อนหน้านี้ในคำถามอื่นใช้-E
คริสมัวร์

1
ฉันพบปัญหาขณะทำงานบน OS X แต่จะส่งคืน IP มากกว่าหนึ่งรายการเป็น IP ดูเหมือนว่าคนแรกเป็นคนที่ถูกต้อง แต่ก็ยังคงนี้จะทำลายตรรกะของฉัน ดูgist.github.com/ssbarnea/31b9dcb0f8fd528b958c - มันจะคืนค่า vnic ที่แอ็คทีฟ แต่ถูกใช้โดย paralles
sorin

13
OSX: ipconfig getifaddr en0
parleer

232

ต่อไปนี้จะทำงานบน 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

8
วิธีการที่ได้รับที่อยู่แรกที่ผลิตโดยที่hostname -Iไม่น่าเชื่อถือเพราะ (ตามเอกสาร) หนึ่งไม่สามารถตั้งสมมติฐานใด ๆ เกี่ยวกับคำสั่งของที่อยู่ ดังนั้นอาจเป็นเครือข่ายภายใน (เช่นเครือข่ายที่มีเครื่องเสมือนอยู่) วิธีอื่นดูเหมือนดี
Adam Ryczkowski

3
นี่ควรเป็นคำตอบที่ยอมรับเนื่องจาก RHEL 7 ไม่รวม ifconfig อีกต่อไป
Andrew

10
สำหรับฉันip route get 1 | awk '{print $(NF-2);exit}'ทำงานตามที่ฉันได้รับผนวกเข้ากับ outptut
Hritik

13
นี้ (คนแรก) เป็นวิธีที่ถูกต้องเท่านั้น สิ่งสำคัญคือต้องอ่าน IP เฉพาะจากอินเทอร์เฟซที่เชื่อมโยงกับเส้นทางเริ่มต้น ไม่เช่นนั้นคุณอาจได้รับที่อยู่ภายในที่ไม่คุ้มค่า
Jan Hudec

12
มันใช้งานไม่ได้สำหรับฉัน แต่มันปิดพอ:ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
estani

230

สำหรับเครื่อง linux (ไม่ใช่ OS X):

hostname --ip-address

10
ใช้งานได้ก็ต่อเมื่อชื่ออยู่ใน DNS ถ้าไม่ใช่คุณจะได้รับข้อความ "ชื่อโฮสต์: ชื่อหรือบริการที่ไม่รู้จัก"
Vebjorn Ljosa

39
hostname -iเป็นรูปแบบสั้นเทียบเท่า
พอลอีแวนส์

75
บางครั้งสิ่งนี้จะคืนค่าเพียง 127.0.0.1 หากมีให้ใช้ชื่อโฮสต์ที่ดีกว่า--I
jrierab

1
มันไม่ทำงานบน Linux อย่างน้อยก็ไม่ได้ใช้hostnameใน GNU Coreutils เวอร์ชัน 8.26
แอ๊

5
บนเครื่องของฉันhostname -iให้เฉพาะ IP ในท้องถิ่นในขณะที่hostname -Iให้ IP อื่น ๆ ทั้งหมด
Alexis Paques

62

บน Linux

hostname -I

บน macOS

ipconfig getifaddr en0

hostname -Iสามารถกลับมาอยู่หลายในลำดับที่ไม่น่าเชื่อถือ (ดูmanpage ) แต่สำหรับฉันมันเป็นเพียงแค่ผลตอบแทนซึ่งเป็นสิ่งที่คุณต้องการhostname192.168.1.X


1
สำหรับฉันมันเป็นhostname -iที่ต่ำกว่าฉัน
พอล Woitaschek

2
@PaulWoitaschek manpage สำหรับตัวพิมพ์เล็กธงบอกว่านี่:-i Avoid using this option; use hostname -I instead
บอริส

@ Boris หากคุณกำลังทำงานในบางสิ่งบางอย่างเช่นนักเทียบท่าที่ใช้งานอัลไพน์ (และ BusyBox) จะยอมรับเฉพาะธงตัวพิมพ์เล็ก
--i

40

สารละลาย

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

คำอธิบาย

ที่ถูกต้องวิธีการเครือข่ายข้อมูลแบบสอบถามใช้ip:

  • -o เอาต์พุตบรรทัดเดียว
  • route get to รับเส้นทางเคอร์เนลจริงไปยังปลายทาง
  • 8.8.8.8 Google IP แต่สามารถใช้ IP จริงที่คุณต้องการเข้าถึง

เช่นipเอาท์พุท:

8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \   cache

ในการแยกsrcip นั้นsedเป็น ligthest และเข้ากันได้ดีที่สุดกับการสนับสนุน regex:

  • -n ไม่มีการส่งออกโดยค่าเริ่มต้น
  • 's/pattern/replacement/p' รูปแบบการจับคู่และการแทนที่การพิมพ์เท่านั้น
  • .*src \([0-9.]\+\).* จับคู่ src IP ที่ใช้โดยเคอร์เนลเพื่อเข้าถึง 8.8.8.8

เช่นผลลัพธ์สุดท้าย:

192.168.8.16

คำตอบอื่น ๆ

ฉันคิดว่าคำตอบก่อนหน้านี้ไม่มีคำตอบที่ดีพอสำหรับฉันเพราะพวกเขาไม่ได้ทำงานในเครื่องที่ผ่านมา (Gentoo 2018)

ปัญหาที่ฉันพบด้วยคำตอบก่อนหน้านี้:

  • การใช้คอลัมน์ตำแหน่งในเอาต์พุตคำสั่ง
  • การใช้ifconfigที่เลิกใช้แล้วและ - ตัวอย่าง - ห้ามลิส IP หลายตัว;
  • ใช้awkสำหรับงานง่าย ๆ ที่สามารถจัดการได้ดีกว่า;
  • ip route get 1 ไม่ชัดเจนและจริง ๆ แล้วเป็นนามแฝงสำหรับ ip route get to 1.0.0.0
  • ใช้hostnameคำสั่งซึ่งไม่มี-Iตัวเลือกในอุปกรณ์ทั้งหมดและส่งคืน127.0.0.1ในกรณีของฉัน

34

แก้ไขแล้ว ( 2014-06-01 2018-01-09)

สำหรับการตั้งค่าที่แข็งแกร่งกับการเชื่อมต่อจำนวนมากและหลาย IP กำหนดค่าบนอินเตอร์เฟซที่แต่ละผมเขียนทุบตีบริสุทธิ์สคริปต์ (ไม่อยู่บนพื้นฐาน127.0.0.1) สำหรับการค้นหาอินเตอร์เฟซที่ถูกต้องและ IP, default routeขึ้นอยู่กับ ฉันโพสต์สคริปต์นี้ที่ด้านล่างสุดของคำตอบนี้

Intro

ในฐานะที่เป็นทั้งระบบปฏิบัติการมี ติดตั้งโดยค่าเริ่มต้นมีเคล็ดลับทุบตีสำหรับ 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.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
}

การใช้งาน:

getMyIP
192.168.1.37

หรือใช้ฟังก์ชันเดียวกัน แต่มีอาร์กิวเมนต์:

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

หมายเหตุ:โดยไม่ต้องโต้แย้งเอาท์พุทฟังก์ชั่นนี้ใน STDOUT, ทรัพย์สินทางปัญญาและการขึ้นบรรทัดใหม่ด้วยการโต้แย้งไม่มีอะไรจะพิมพ์ แต่ตัวแปรชื่อเป็นอาร์กิวเมนต์จะถูกสร้างขึ้นและมี IP โดยไม่ต้องขึ้นบรรทัดใหม่

Nota2:สิ่งนี้ได้รับการทดสอบบน Debian, LaCie ที่ถูกแฮ็ก nas และ MaxOs หากสิ่งนี้ไม่ได้ผลภายใต้สภาพแวดล้อมของคุณฉันจะสนใจด้วยการดึงข้อมูลกลับมา!

รุ่นเก่าของคำตอบนี้

(ไม่ถูกลบเพราะอ้างอิงsedไม่ใช่bash)

เตือน: มีปัญหาเกี่ยวกับตำแหน่งที่ตั้ง!

เร็วและเล็ก:

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

ระเบิด (ทำงานด้วย;)

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

แก้ไข:

วิธี! ดูเหมือนว่าจะไม่ทำงานบน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):

สคริปต์นี้จะค้นหาเส้นทางเริ่มต้นและส่วนต่อประสานที่คุณใช้ก่อนจากนั้นค้นหาเครือข่ายการจับคู่ไอพีท้องถิ่นของเกตเวย์และเติมตัวแปร สองบรรทัดสุดท้ายเพิ่งพิมพ์สิ่งที่ชอบ:

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} $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
@ โซริน: ใช่แล้วตอนนี้ใช้ได้กับ ifconfig แล้ว (ตามที่sbinไม่ได้อยู่ใน$PATHfullpath ของฉันจะต้องมีการระบุ แต่มีเส้นทางเดียวกันบน MacOS ด้วยเช่นกัน :-)
F. Hauri

1
@sorin ลองนี้มีtimeให้เลือกคุณจะใช้นานมาก ...
เอฟ HAURI

วิธีแก้ปัญหาที่รวดเร็วและเล็กเป็นวิธีที่ดีที่สุด โซลูชันที่ใหม่กว่านั้นทำให้ฉันมีข้อผิดพลาดทางไวยากรณ์ ความเข้ากันได้เป็นข้อดีเสมอ ขอบคุณ.
m3nda

29

เฉพาะบางรุ่นของ Ubuntu เท่านั้น แม้ว่ามันอาจจะบอกคุณ127.0.0.1:

hostname  -i

หรือ

hostname -I

ทำงานในทุกกรณีหรือไม่
AloneInTheDark

6
ไม่ - มันอาจบอกคุณได้ 127.0.0.1
SvenDowideit

ชื่อโฮสต์ - ฉันทำงานบน Ubuntu
Borzh

1
$ hostname --ip-addressเพียงแค่ให้ฉัน127.0.0.1กับ Arch Linux
27732

1
ใช้ชื่อโฮสต์ -I หรือชื่อโฮสต์ --all-ip-addresses
Aydin K.

24

คุณสามารถรับที่อยู่ IP รุ่น 4 ของ eth0 โดยใช้คำสั่งนี้ใน linux

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

ผลผลิตจะเป็นเช่นนี้

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

คำตอบที่ดีที่สุดสำหรับฉัน! ขอบคุณ @Sathish! ;-)
ซามูเอลฟาน

1
ฉันเห็นด้วยนี่เป็นวิธีที่สะอาดที่สุดในการรับ IPv4 ของ eth0
Chris Mendez

สิ่งนี้ถือว่า eth0 ซึ่งไม่ใช่กลยุทธ์การตั้งชื่อปัจจุบันและไม่เคยรับประกันว่าจะเป็นอินเทอร์เฟซหลัก
rfay

นี่เป็นวิธีที่หรูหราที่สุดหากคุณรู้จักส่วนต่อประสาน เหมาะอย่างยิ่งหากระบบของคุณมีอินเทอร์เฟซหลายตัว แต่คุณสนใจสิ่งใดสิ่งหนึ่ง
lepe

14

สิ่งนี้ใช้ได้กับ Linux และ OSX

นี่จะเป็นอินเทอร์เฟซที่เชื่อมโยงกับเส้นทางเริ่มต้น

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

ใช้อินเทอร์เฟซที่ค้นพบข้างต้นรับที่อยู่ 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

แล็ปท็อปดาร์วิน 14.4.0 เคอร์เนลดาร์วินรุ่น 14.4.0: พฤ. 28 พฤษภาคม 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 พฤหัสบดี 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


แม้จะมีคำตอบสำหรับคำถามนี้ทั้งหมด แต่คำถามนี้ดูเหมือนจะเป็นคำตอบเดียวที่ถูกต้องจริง เพียงแค่ต้องการ| head -1ที่ท้ายบรรทัดแรกเพื่อรับส่วนต่อประสานเริ่มต้นและส่วนที่เหลือก็ดี
Endareth

12

การใช้วิธีการอื่นคุณอาจป้อนข้อขัดแย้งที่กำหนดที่อยู่ IP หลายรายการไว้ในระบบ บรรทัดนี้รับที่อยู่ IP ตามค่าเริ่มต้นที่ใช้เสมอ

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

มันจะล้มเหลวหากไม่มีเส้นทางเริ่มต้น (แต่เป็นความคิดที่ดี)
FractalSpace

ดี ... สมมติว่าทำงานแม้ว่าคุณจะไม่มีอินเทอร์เน็ตเหรอ?
Boris Churzin

8

ฉันกำลังแยกความคิดเห็นของฉันออกจากคำตอบนี้:

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

มันขึ้นอยู่กับคำตอบ @CollinAnderson ซึ่งไม่ได้ทำงานในกรณีของฉัน


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

1
หากคุณต้องการทำให้สิ่งนี้เป็นbashนามแฝง:alias myip="ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print \$2}'"
Sam Houston

ขวา. แต่คำถามแรกเกี่ยวกับคำสั่ง ดังนั้นฉันเพิ่งโพสต์ที่เกี่ยวข้อง ไชโย!
Faizan Noor

6

วิธีที่สั้นที่สุดในการรับที่อยู่ ipv4 ในระบบลินุกซ์ของคุณ:

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

5
ไม่ดี หน้าคนบอกคุณโดยเฉพาะที่จะไม่ทำให้สมมติฐานใด ๆ เกี่ยวกับลำดับของการส่งออก
แมตต์

ใช้งานได้ดีสำหรับกรณีการใช้งานเล็กน้อยของฉัน - ฉันไม่สนใจว่ามันจะรวดเร็วและสกปรก! ที่ดี!
Nicolai Weitkemper

6

สมมติว่าคุณต้องการIP สาธารณะหลักของคุณตามที่เห็นจากส่วนอื่น ๆ ของโลกลองทำสิ่งต่อไปนี้:

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

6

ฉันต้องเพิ่ม Collin Andersons ตอบว่าวิธีนี้ยังคำนึงถึงถ้าคุณมีสองอินเตอร์เฟสและพวกเขาทั้งสองปรากฏขึ้น

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

ฉันทำงานกับแอปพลิเคชั่นของ Raspberry Pi และต้องการที่อยู่ IP ที่ใช้งานจริงไม่ว่าจะเพิ่มหรือไม่ก็ตาม คำตอบอื่น ๆ ส่วนใหญ่จะส่งคืนทั้งที่อยู่ IP ซึ่งไม่จำเป็นต้องเป็นประโยชน์สำหรับสถานการณ์ของฉัน


5

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

ค้นหาที่อยู่ IP ของคอมพิวเตอร์นี้ในเครือข่ายซึ่งเป็นเกตเวย์เริ่มต้น (ตัวอย่างเช่นไม่รวมเครือข่ายเสมือนทั้งหมดสะพานนักเทียบท่า) เช่น เกตเวย์อินเทอร์เน็ต, เกตเวย์ wifi, อีเธอร์เน็ต

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

ทำงานบน Linux

ทดสอบ:

  ~ 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

ดี! การเขียนโปรแกรม Taco Bellที่ดีที่สุด - ขอบคุณสำหรับสิ่งนี้
Stevie Howard


3

ifconfigตัวแปรอื่นที่ใช้งานได้ทั้งบน Linux และ OSX:

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

1
รูปแบบหนึ่งที่มีขนาดเล็ก:ifconfig | grep '\<inet\>' | cut -d ' ' -f2 | grep -v '127.0.0.1'
jpbochi

เหตุใดครึ่งหนึ่งของคำตอบเหล่านี้จึงไม่ทำงานเลยสำหรับฉัน
SurpriseDog

3

ฉันผ่านลิงค์จำนวนมาก (StackExchange, AskUbuntu, StackOverflow และอื่น ๆ ) และมาถึงการตัดสินใจที่จะรวมโซลูชันที่ดีที่สุดทั้งหมดไว้ในเชลล์สคริปต์หนึ่งชุด

ในความคิดของฉันทั้งสอง QA ที่ดีที่สุดที่เห็น:

ฉันจะรับที่อยู่ 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 "$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

ฉันเพียงแค่ใช้ประโยชน์จากเครือข่ายการเชื่อมต่อรายชื่อคำสั่งที่กำหนดเองของฉันคือ

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

ในสมุดบันทึกของฉันเอง

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

แต่ถ้าอินเทอร์เฟซเครือข่ายเป็นเจ้าของอย่างน้อยหนึ่ง ip มันจะแสดง ip ทั้งหมดที่เป็นของมัน

ตัวอย่างเช่น

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

ดูเหมือนว่าคำสั่งที่ip route get 1 | awk '{print $NF;exit}'ให้ไว้โดยลิงก์มีความแม่นยำมากขึ้นยิ่งไปกว่านั้นยิ่งสั้น


2

ไม่แน่ใจว่าใช้งานได้กับทุกระบบปฏิบัติการหรือไม่

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

ใช้งานไม่ได้กับ CentOS 7.0
Benoit Blanchon

@BenoitBlanchon ip route get 1 | awk '{print $NF;exit}'จากนั้นใช้นี้ ควรทำงานกับระบบส่วนใหญ่
Jotne

ใช้ip route get 1 | awk '{print $NF;exit}'งานได้จริง
Benoit Blanchon

2

มีแพ็คเกจโหนดสำหรับทุกสิ่ง มันเป็นแพลตฟอร์มข้ามและใช้งานง่าย

$ npm install --global internal-ip-cli

$ internal-ip
fe80::1

$ internal-ip --ipv4
192.168.0.3

นี่เป็นวิธีการโต้เถียง แต่การใช้ npm สำหรับการทำเครื่องมือกำลังเป็นที่นิยมมากขึ้นเช่นมันหรือไม่


1

หากคุณรู้ว่าอินเตอร์เฟสเครือข่าย (eth0, wlan, tun0 ฯลฯ ):

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

ใช้งานได้บน Mac, Linux และภายใน Docker Containers:

$ 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; ทางออก} ')

ยังทำงานบน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]*).*/\2/p' | awk '{print $1; exit}')}


Mac ไม่ทำงาน: hostname --ip-address=> hostname: illegal option -- -บน macOS Sierra
JL Peyret

1

สำหรับ linux สิ่งที่คุณต้องการคือคำสั่งนี้:

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

พิมพ์สิ่งนี้ในเปลือกของคุณและคุณก็จะรู้ว่า IP


ไม่มันไม่ทำงาน
FractalSpace


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.