จะรับที่อยู่ IP ของฉันเองและบันทึกลงในตัวแปรในเชลล์สคริปต์ได้อย่างไร


65

ฉันจะรับที่อยู่ IP ของตัวเองและบันทึกลงในตัวแปรในเชลล์สคริปต์ได้อย่างไร


2
คำเตือน: มีคำตอบ "ทำงานในระบบของฉัน" มากมายที่นี่ซึ่งอาจไม่สามารถพกพาไปยังสภาพแวดล้อมอื่นได้ คุณต้องตัดสินใจว่าคุณต้องการสิ่งที่เหมาะกับคุณหรือบางอย่างที่สามารถแบ่งปันได้ ทุกระบบมีหลาย IP วิธีการแก้ปัญหาแบบพกพาที่ตอบคำถาม: "สิ่งที่ IP ฉันจะใช้ในการเข้าถึงblah ?" ผลงานในการแก้ปัญหาระบบของฉันตอบคำถาม: "สิ่งที่อยู่ IP ของฉัน?" ด้วย A: "ฉันคิดว่าคุณหมายถึงอันนี้…" นี่ควรจะเป็นunix.stackexchange.com/a/402160/9745
บรูโน่บรองโกสกี

นี่เป็นวิธีการขอรับแบบฟอร์มที่อยู่ IP / proc: unix.stackexchange.com/questions/365225/…
Pierz

คำตอบ:


30

ไม่ใช่เรื่องง่ายถ้าคุณต้องการคำนึงถึง wlan และอินเทอร์เฟซทางเลือกอื่น ๆ หากคุณทราบว่าอินเทอร์เฟซใดที่คุณต้องการที่อยู่ (เช่น eth0 การ์ดอีเทอร์เน็ตใบแรก) คุณสามารถใช้สิ่งนี้:

ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"

กล่าวอีกนัยหนึ่งขอข้อมูลการกำหนดค่าเครือข่ายให้ฉันค้นหาeth0รับบรรทัดนั้นและบรรทัดถัดไป ( -A 1) รับเฉพาะบรรทัดสุดท้ายรับส่วนที่สองของบรรทัดนั้นเมื่อแยกด้วย:แล้วรับส่วนแรกเมื่อแยก มีพื้นที่


1
ฉันได้เพิ่มส่วนเพิ่มเติมgrepในรหัสของคุณเพื่อละเว้นส่วนต่อประสานใด ๆ ที่มี "eth0:" อยู่ในนั้น ตอนนี้ใช้งานได้ตามที่คาดหวัง (ให้เฉพาะที่อยู่ IP "eth0" และไม่ใช่อินเทอร์เฟซย่อยใด ๆ (eth0: 0, eth0: 1, ฯลฯ ):ip="$(ifconfig | grep -v 'eth0:' | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"

6
คุณสามารถข้าม grep แรกโดยใช้ifconfig eth0
Bryan Larsen

5
ifconfig ไม่ได้รับการสนับสนุนคุณควรใช้ip addressแทน
alexises

70

ฉันเชื่อว่าวิธี "เครื่องมือที่ทันสมัย" ในการรับที่อยู่ ipv4 ของคุณคือการแยกวิเคราะห์ 'ip' แทน 'ifconfig' ดังนั้นมันจึงเป็นเช่น:

ip4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
ip6=$(/sbin/ip -o -6 addr list eth0 | awk '{print $4}' | cut -d/ -f1)

หรืออะไรทำนองนั้น


4
ipมีให้ใน Red Hat และ Fedora distros ทั้งหมดที่ฉันเคยใช้ ipเป็นส่วนหนึ่งของแพ็คเกจ iproute2 ( linuxfoundation.org/collaborate/workgroups/networking/iproute2 ) ifconfigและrouteคาดว่าจะถูกปฏิเสธแม้ว่าพวกเขาจะยังคงถูกใช้งานโดยผู้คนจำนวนมากโดยเฉพาะอย่างยิ่งในสคริปต์ ipแยกได้มากขึ้นใน opionion ของฉัน
jsbillings

3
ipยังมีให้ในดิสทริบิวชันที่เป็นพื้นฐานของ Debian และ Debian ทั้งหมดที่ฉันเคยเห็น เป็นส่วนหนึ่งของแพ็คเกจ iproute ซึ่งมีการทำเครื่องหมายว่าสำคัญ
Arrowmaster

2
นี่เป็นวิธีที่ควรทำฉันจะลงคะแนนคำตอบอื่น ๆ สำหรับการใช้ ifconfig ipเป็นส่วนหนึ่งของแพ็คเกจ iproute2 ซึ่งมีค่า distro เป็นจำนวนมากตามค่าเริ่มต้น มันอยู่ใน repos ที่ดีที่สุดที่จะ en.wikipedia.org/wiki/Iproute2
jwbensley

3
@jsbillings ทำไม/sbin/ipแทนip?
l0b0

1
นี่คือคำตอบที่ยอดเยี่ยม! การรวมกันของawkและcutเป็นที่น่าขบขันอย่างอ่อนโยนต่อฉันนี่เป็นทางเลือกที่เป็นไปได้ซึ่งอาจไม่ดีกว่าจริง ๆ :ip -o -4 addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'
สวิส

32

ทำไมไม่เพียงแค่ทำIP=$(hostname -I)?


3
hostname -iให้ฉันเพียง127.0.0.1, hostname -Iให้ฉันที่ถูกต้อง IP-อยู่ ...
นักเรียน

@ นักเรียนใช่แน่นอนฉันได้ทดสอบมันบนเครื่องที่สามารถแก้ไขชื่อโฮสต์ได้ตามที่ manpage พูด-i Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses
Andrei

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

วิธีที่ง่ายที่สุดคือการเพิ่มลงไป/etc/hostsพร้อมกับที่อยู่ IP ที่สอดคล้องกัน
Andrei

3
ไม่-Iใช้ FreeBSD แต่คุณสามารถใช้งานได้dig +short `hostname -f`
Tigger

24

หากคุณต้องการที่อยู่ของอินเทอร์เฟซวิธีที่ง่ายที่สุดคือติดตั้งโปรแกรมเพิ่มเติมแล้ว:

anthony@Zia:~$ ifdata -pa br0
172.16.1.244

ifdataตอบคำถามทุกข้อที่คุณอยากให้แยกวิเคราะห์ifconfigออกมา

หากคุณต้องการทราบที่อยู่ IP ของคุณตามที่เห็นภายนอก (นอกเหนือจาก NAT ใด ๆ ฯลฯ ) มีบริการมากมายที่จะทำ หนึ่งค่อนข้างง่าย:

anthony@Zia:~$ curl ifconfig.me
173.167.51.137

โอ้พระเจ้าขอบคุณสำหรับคำตอบนี้ ไม่เคยได้ยินมาก่อนเลย ฉันกำลังพิจารณาอย่างจริงจังที่จะเขียนโปรแกรม C เล็ก ๆ ของฉันเองเพื่อทำสิ่งนั้น
Chris Harrington

มันจะดีที่จะได้เพิ่มเข้าไปifdata iproute2อาจเป็นเลขฐานสองใหม่ที่เรียกว่าipdata
สวิส

ifdata นั้นดี แต่มันไม่รองรับ ipv6
BringBackCommodore64

15

ในการรับที่อยู่ IPv4 และ IPv6 และไม่ถือว่าส่วนต่อประสานหลักคือeth0(วันนี้em1 เป็นเรื่องปกติมากขึ้น ) ลอง:

ips=$(ip -o addr show up primary scope global |
      while read -r num dev fam addr rest; do echo ${addr%/*}; done)
  • -oใช้รูปแบบการออกหนึ่งบรรทัดซึ่งจะง่ายต่อการประมวลผลด้วยread, grepฯลฯ
  • up ไม่รวมอุปกรณ์ที่ไม่ได้ใช้งาน
  • scope globalยกเว้นที่อยู่ส่วนตัว / ท้องถิ่นเช่น127.0.0.1และfe80::/64
  • primaryยกเว้นที่อยู่ชั่วคราว (สมมติว่าคุณต้องการที่อยู่ที่ไม่เปลี่ยนแปลง)

1
นี่ต้องเป็นคำตอบที่ดีที่สุดเพราะ 1) มันไม่ถือว่าชื่ออุปกรณ์ 2) ใช้ 'ip' ซึ่งต่างจากโรงเรียนเก่า 'ifconfig' และ 3) รองรับ ipv6 เช่นกัน
BringBackCommodore64

ฉันเห็นด้วยมันเป็นการเริ่มต้นที่ดีที่สุดสำหรับกรณีใช้งานส่วนใหญ่ คุณสามารถผ่าน-4/ -6เพื่อกรองประเภทที่อยู่ คุณยังสามารถรับพารามิเตอร์อินเทอร์เฟซอื่น ๆ ได้อย่างง่ายดาย โดยส่วนตัวแล้วฉันไม่ชอบในขณะที่วงและฉันชอบgrep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
Jérôme Pouiller

7

ขึ้นอยู่กับสิ่งที่คุณหมายถึงโดยที่อยู่ IP ของตัวเอง ระบบมีที่อยู่ IP ในเครือข่ายย่อยหลายแห่ง (บางครั้งอาจมีหลายต่อซับเน็ต) บางแห่งซึ่ง IPv4, IPv6 บางเครื่องที่ใช้อุปกรณ์เช่นอะแดปเตอร์อีเธอร์เน็ต, อินเตอร์เฟสลูปแบ็ค, อุโมงค์ VPN, บริดจ์, อินเตอร์เฟสเสมือน ...

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

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

สำหรับ IPv4 (อาจใช้งานกับ IPv6 ได้เช่นกัน) เคล็ดลับที่ทำงานในหลาย Unices รวมถึง Linux เพื่อค้นหาที่อยู่ IP ของอินเตอร์เฟสที่ใช้เพื่อเข้าถึงโฮสต์ที่กำหนดคือการใช้การเชื่อมต่อ (2) บนซ็อกเก็ต UDP และใช้ getsockname ():

ตัวอย่างเช่นบนคอมพิวเตอร์ที่บ้านของฉัน:

perl -MSocket -le 'socket(S, PF_INET, SOCK_DGRAM, getprotobyname("udp"));
connect(S, sockaddr_in(1, inet_aton("8.8.8.8")));
print inet_ntoa((sockaddr_in(getsockname(S)))[1]);'

จะถูกใช้เพื่อค้นหาที่อยู่ IP ของอินเทอร์เฟซที่ฉันจะไปถึง 8.8.8.8 (เซิร์ฟเวอร์ DNS ของ Google) มันจะส่งคืนบางสิ่งเช่น "192.168.1.123" ซึ่งเป็นที่อยู่ของอินเทอร์เฟซสำหรับเส้นทางเริ่มต้นไปยังอินเทอร์เน็ต อย่างไรก็ตาม google จะไม่เห็นคำขอ DNS จากเครื่องของฉันว่ามาจากที่อยู่ IP นั้นซึ่งเป็นรหัสส่วนตัวเนื่องจากมี NAT ที่ดำเนินการโดยเราเตอร์บรอดแบนด์ในบ้านของฉัน

เชื่อมต่อ () บนซ็อกเก็ต UDP ไม่ได้ส่งแพ็คเก็ตใด ๆ (UDP คือการเชื่อมต่อน้อย) แต่เตรียมซ็อกเก็ตโดยการสอบถามตารางเส้นทาง


7
ipa=$(ip route get 8.8.8.8| grep src| sed 's/.*src \(.*\)$/\1/g')

ipa=$(hostname -i|cut -f2 -d ' ')

1
ใช้-Iแทน-iจะดีกว่าที่คุณต้องการละเว้นที่อยู่ลูปแบ็คดังนั้นคำสั่งสุดท้ายจะเป็นipa=$(hostname -I|cut -f1 -d ' ')
Karl.S

1
ถ้าgrepไม่พออย่าไปทำอย่างอื่น เพียงแค่ใช้บางสิ่งบางอย่างอื่น ( sed, awkฯลฯ )
Bruno Bronosky

7

ฉันไม่ได้ตั้งใจที่จะกระตุก แต่มีวิธีที่ถูกต้องและนี่คือมัน คุณตัดทอนผลลัพธ์ของip routeการรับเฉพาะ IP ต้นทาง "ที่อยู่ IP ของฉัน" (คำของ OP) ขึ้นอยู่กับว่าคุณพยายามเข้าถึง IP ใด หากคุณสนใจที่จะเข้าถึงอินเทอร์เน็ตสาธารณะการใช้เซิร์ฟเวอร์ DNS 8.8.8.8 ของ Google นั้นเป็นมาตรฐานที่ค่อนข้างดี ดังนั้น...

คำตอบสั้น ๆ คือ:

ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'

นี่คือคำอธิบายโดยละเอียด

ถ้าฉันต้องการ IP ที่ฉันใช้เพื่อเข้าถึงอินเทอร์เน็ตฉันจะใช้สิ่งนี้:

pi@et3:~ $ ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
10.55.0.200

ถ้าฉันต้องการ IP ที่ฉันใช้เพื่อเข้าถึงบางสิ่งบนVPNของฉันฉันจะใช้สิ่งนี้:

pi@et3:~ $ ip route get 172.31.0.100 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
172.29.0.9

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

ถ้าฉันต้องการ IP ที่ฉันใช้เพื่อเข้าถึงตัวเองฉันจะใช้สิ่งนี้:

pi@et3:~ $ my_ip=$(getent hosts $(cat /etc/hostname) | awk '{print $1; exit}')
pi@et3:~ $ ip route get $my_ip | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
127.0.0.1

เพิ่มเติมเกี่ยวกับsedคำสั่งนั้น

ก่อนอื่นให้ฉันบอกว่าเมื่อเลือกเครื่องมือ unix คุณลองเลือกเครื่องมือที่ต้องการท่อที่น้อยที่สุด ดังนั้นในขณะที่คำตอบบางอย่างจะท่อifconfigเพื่อgrepที่จะsedไปheadนั่นคือไม่ค่อยเคยจำเป็น เมื่อคุณเห็นมันควรยกธงสีแดงที่คุณรับคำแนะนำจากใครบางคนที่มีประสบการณ์น้อย นั่นไม่ได้ทำให้ "การแก้ปัญหา" ผิด แต่มันอาจใช้การทำให้เพรียวบางได้

ผมได้เลือกเพราะมันคือสั้นกว่าขั้นตอนการทำงานที่เหมือนกันในsed awk(ฉันมีตั้งแต่ตัวอย่างเล็ก ๆ น้อย ๆ ด้านล่าง) ฉันไม่คิดว่าเครื่องมืออื่น ๆ แต่ทั้งสองจะเหมาะสม

ตรวจสอบสิ่งที่sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'ทำ:

sed            # the sed executable located via $PATH
-n             # no output unless explicitly requested
'              # begin the command space
/src/          # regex match the string 'src'
{              # begin a block of commands **
s/             # begin a substitution (match)
  .*src *      # match anything leading up to and including src and any number of spaces
  \([^ ]*\)    # define a group containing any number of non spaces
  .*           # match any trailing characters (which will begin with a space because of the previous rule).
/              # begin the substitution replacement
  \1           # reference the content in the first defined group
/              # end the substitution
p              # print (explicitly, remember) the result
;              # designate the end of the command
q              # quit
}              # end the block of commands
'              # end the command space

** all of which will be performed "on match"
  - otherwise only the first command to following the match would be performed "on match"
    - any other commands would be performed whether there was a match or not
บันทึก:

ฉันเคยใช้sed -n '/src/{s/.*src *//p;q}'แต่ผู้วิจารณ์ชี้ให้เห็นว่าบางระบบมีข้อมูลต่อท้ายหลังจากsrcฟิลด์

ใช้ awk

ip route get 8.8.8.8 | \
    awk '{gsub(".*src",""); print $1; exit}'

# or

ip route get 8.8.8.8 | \
    awk '{for(i=1; i<NF; i++){if($i=="src"){i++; print $i; exit}}}'

เพิ่มเติมเกี่ยวกับเครือข่ายของฉัน

รายการของฉันifconfigที่ฉันมีtun0สำหรับ VPN และeth0สำหรับ LAN ของฉัน

pi@et3:~ $ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.55.0.200  netmask 255.255.252.0  broadcast 10.55.3.255
        inet6 fe80::71e6:5d7c:5b4b:fb25  prefixlen 64  scopeid 0x20<link>
        ether b8:27:eb:b2:96:84  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 172.29.0.9  netmask 255.255.255.255  destination 172.29.0.10
        inet6 fe80::3a8e:8195:b86c:c68c  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)

wlan0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether b8:27:eb:e7:c3:d1  txqueuelen 1000  (Ethernet)

ip route get 8.8.8.8 | sed -n '/src/{s/.*src *//p;q}'10.1.2.3 uid 1002ให้ฉัน ดังนั้นฉันเพิ่มเพื่อผนวก| awk '{print $1}'เฉพาะที่อยู่ IP
wisbucky

@wuckyucky ฉันไม่เคยไปป์ sed / awk / grep กันในรหัสที่บันทึกไว้ (ฉันจะใช้มันในบรรทัดคำสั่งเมื่อฉันรีบ แต่คุณจะไม่พบมันเขียนไปยังดิสก์อื่นนอกเหนือจาก ~ / .bash_history ของฉัน) ฉันปรับปรุงคำตอบที่จะใช้ awk และแก้ปัญหานี้
Bruno Bronosky

1
@wuckyucky ฉันไม่สามารถยืนได้ ฉันทำให้ฉันทำงานกับสภาพแวดล้อมของคุณด้วย
Bruno Bronosky

2

บน FreeBSD คุณสามารถใช้

dig +short `hostname -f`

สิ่งนี้อาจทำงานได้ในสภาพแวดล้อมอื่นขึ้นอยู่กับการตั้งค่าของคุณ


ฉันเชื่อว่าสิ่งนี้ขึ้นอยู่กับการกำหนดค่า/etc/resolv.confและวิธีที่เราเตอร์เครือข่ายจัดการกับชื่อโฮสต์ในเครื่อง ไม่ควรใช้สิ่งนี้ในสภาพแวดล้อมของคุณหากคุณทดสอบและใช้งานได้ แต่ถ้าคุณทำเช่นนั้นคุณกำลังสร้างระบบ "เปราะ" ที่จะทำให้เกิดปัญหาอื่น ๆ หากคุณแบ่งปันสิ่งนี้ ใช้ด้วยความระมัดระวัง
Bruno Bronosky

2

สมมติว่าคุณอาจมีอินเตอร์เฟซที่หลากหลายของชื่อต่าง ๆแต่คุณต้องการ non-localhost แรกและไม่ใช่ ipv6 คุณอาจลอง:

ip=`ip addr show |grep "inet " |grep -v 127.0.0. |head -1|cut -d" " -f6|cut -d/ -f1`

ip = $ (ifconfig | grep -oP '(? <= inet addr:) \ S *' | grep -v 127)
rcjohnson

1

ฉันใช้หนึ่งซับนี้:

IP=$(/sbin/ifconfig | grep -e "inet:" -e "addr:" | grep -v "inet6" | grep -v "127.0.0.1" | head -n 1 | awk '{print $2}' | cut -c6-)

ใช้งานifconfig(ใช้ได้อย่างกว้างขวาง) ไม่ใช้ที่localhostอยู่ไม่ผูกคุณกับชื่ออินเทอร์เฟซที่กำหนดไม่คำนึงถึง IPv6 และพยายามรับ IP ของอินเทอร์เฟซเครือข่ายแรกที่พร้อมใช้งาน



1

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

หากคุณต้องการที่อยู่ IPv4 สำหรับอินเตอร์เฟส Ethernet ของคุณeth0:

$ ip -4 -o addr show eth0 | awk '{print $4}'
192.168.1.166/24  

เป็นสคริปต์:

$ INTFC=eth0  
$ MYIPV4=$(ip -4 -o addr show $INTFC | awk '{print $4}') 
$ echo $MYIPV4
192.168.1.166/24

เอาต์พุตที่สร้างขึ้นด้านบนอยู่ในรูปแบบCIDR หากไม่ต้องการสัญกรณ์ CIDR สามารถถอดออกได้:

$ ip -4 -o addr show eth0 | awk '{print $4}' | cut -d "/" -f 1 
192.168.1.166  

ตัวเลือกอื่นที่ IMHO นั้น "หรูหราที่สุด" จะได้รับที่อยู่ IPv4 สำหรับอินเทอร์เฟซใดก็ตามที่ใช้เพื่อเชื่อมต่อกับโฮสต์ระยะไกลที่ระบุ (8.8.8.8 ในกรณีนี้) ความอนุเคราะห์ของ @gatoatigrado ในคำตอบนี้ :

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

เป็นสคริปต์:

$ RHOST=8.8.8.8  
$ MYIP=$(ip route get $RHOST | awk '{ print $NF; exit }')
$ echo $MYIP
192.168.1.166

สิ่งนี้ทำงานได้ดีบนโฮสต์ที่มีอินเตอร์เฟสเดียว แต่ข้อดีอีกอย่างก็คือจะทำงานกับโฮสต์ที่มีอินเตอร์เฟสหลายตัวและ / หรือข้อกำหนดเส้นทาง

ipจะเป็นวิธีที่ฉันชอบ แต่ก็ไม่ใช่วิธีเดียวที่จะทำให้แมวตัวนี้ นี่เป็นอีกวิธีหนึ่งที่ใช้hostnameหากคุณต้องการบางสิ่งที่ง่ายขึ้น / กระชับยิ่งขึ้น:

$ hostname --all-ip-addresses | awk '{print $1}'  

หรือถ้าคุณต้องการที่อยู่ IPv6:

$ hostname --all-ip-addresses | awk '{print $2}'  

0

ฉันต้องทำสิ่งนี้ภายในนามแฝงเพื่อเริ่มต้นเซิร์ฟเวอร์วิทยุบน NIC แบบใช้สายของฉัน ฉันใช้

ip addr | egrep -i "inet.+eth1" | awk -F[\ /] '{print $6}' | tr -d [:space:]

egrepถูกคิดค่าเสื่อมราคา ใช้grep -Eแทน
Yokai

0

คำสั่งบางคำสั่งทำงานบน centos 6 หรือ 7 คำสั่งด้านล่างใช้กับทั้งสอง

#!/bin/sh

serverip=`/sbin/ifconfig eth0 | grep "inet" | awk '{print $2}' | awk 'NR==1' | cut -d':' -f2`

echo $serverip

grep | awk | awkนั่นคือวิธีที่มากเกินไป บรรทัดสามารถย่อให้เล็กลงได้/sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } '
Archemar

ฉันยอมรับแล้วคุณสามารถตรวจสอบทั้ง centos6 และ 7 ได้ไหม centos 7.x / sbin / ifconfig eth0 | awk '$ 1 == "inet" {print substr ($ 2,6); ต่อไป ; } '35.104.41 centos6.x (ทำงานได้ดี) / sbin / ifconfig eth0 | awk '$ 1 == "inet" {print substr ($ 2,6); ต่อไป ; } '192.168.0.1
lakshmikandan

0

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

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

0

ตัวอย่างนี้หลีกเลี่ยงการเข้ารหัสชื่ออุปกรณ์อย่างหนัก (เช่น 'eth0') และจะใช้ipแทนifconfig:

/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/'

มันจะกลับ IP ip addrของอุปกรณ์ที่ใช้งานครั้งแรกที่ระบุไว้ในการส่งออกของ ขึ้นอยู่กับเครื่องของคุณซึ่งอาจเป็นที่อยู่ ipv4 หรือ ipv6

เพื่อเก็บไว้ในตัวแปรใช้:

ip=$(/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/')

0

วิธีแก้ปัญหาทั้งหมดที่ใช้ awk / sed / grep ดูซับซ้อนเกินไปและน่าเกลียดสำหรับสถานการณ์ของฉัน ... ดังนั้นฉันจึงคิดวิธีแก้ปัญหาที่ง่าย ๆ นี้ แต่ระวัง cus มันตั้งสมมติฐานบางอย่างนั่นคือข้อสันนิษฐานที่ว่าอินเตอร์เฟส LAST เป็นสิ่งที่คุณต้องการ สนใจ. ถ้าคุณโอเคกับสิ่งนี้มันก็ค่อนข้างสะอาด:

ifconfig | awk '/net / { x = $2 } END { print x }'

มิฉะนั้นคุณสามารถทำifประโยคโง่ ๆเพื่อทดสอบคำนำหน้าเฉพาะหรือเกณฑ์ใดก็ได้ที่คุณอาจมี


0

คำสั่งง่าย ๆ ไปยังที่อยู่ IP ที่ดีด้วยอินเตอร์เฟซเริ่มต้น

ip route | grep src | awk '{print $NF; exit}'

ทดสอบบนระบบปฏิบัติการ Unix ทั้งหมด


0

นี่อาจไม่ใช่โซลูชันที่มีประสิทธิภาพหรือถูกต้องที่สุด แต่ไม่เหมือนกับโซลูชันอื่น ๆ ส่วนใหญ่คำสั่งใช้งานได้ทั้ง Linux และ Mac (BSD)

host `hostname` | awk '{print $NF}'

0

หากคุณกำลังมองหาที่อยู่ IP สาธารณะของช่องคุณสามารถใช้สิ่งต่อไปนี้:

  • dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"

คุณสามารถใช้dig(1)ตัวเลือกเช่น-4หรือ-6เพื่อค้นหาที่อยู่ IPv4 หรือ IPv6 โดยเฉพาะ Google จะให้คำตอบในรูปแบบบันทึกTXTซึ่งจะมีเครื่องหมายคำพูดล้อมรอบเมื่อแสดงโดยdig; ถ้าคุณต้องการใช้ตัวแปรกับยูทิลิตี้เช่นtracerouteคุณต้องใช้สิ่งที่ชอบtr (1)เพื่อลบเครื่องหมายคำพูด

ตัวเลือกอื่น ๆ รวมถึงwhoami.akamai.netและmyip.opendns.com, คำตอบAและAAAAบันทึกซึ่ง (แทนที่จะTXTเป็นในตัวอย่างข้างต้นจาก Google) ดังนั้นจึงไม่จำเป็นต้องลบเครื่องหมายคำพูด:

  • dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short

  • dig -4 @resolver1.opendns.com -t any myip.opendns.com +short

  • dig -6 @resolver1.opendns.com -t any myip.opendns.com +short

นี่เป็นสคริปต์ตัวอย่างที่ใช้ตัวเลือกทั้งหมดด้านบนเพื่อตั้งค่าตัวแปร:

#!/bin/sh
IPANY="$(dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
GOOGv4="$(dig -4 @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
GOOGv6="$(dig -6 @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
AKAMv4="$(dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short)"
CSCOv4="$(dig -4 @resolver1.opendns.com -t a myip.opendns.com +short)"
CSCOv6="$(dig -6 @resolver1.opendns.com -t aaaa myip.opendns.com +short)"
printf '$GOOG:\t%s\t%s\t%s\n' "${IPANY}" "${GOOGv4}" "${GOOGv6}"
printf '$AKAM:\t%s\n$CSCO:\t%s\t%s\n' "${AKAMv4}" "${CSCOv4}" "${CSCOv6}"

หากคุณกำลังมองหาที่อยู่ IP ส่วนตัวหรือชุดของที่อยู่ IP ทั้งหมดที่กำหนดให้กับกล่องคุณสามารถใช้การรวมกันของifconfig(บน BSD และ GNU / Linux), ip addr(บน GNU / Linux), hostname(ตัวเลือก-iและ-Iบน GNU / Linux) และnetstatดูว่าเกิดอะไรขึ้น


-2
hostname -I >> file_name 

สิ่งนี้จะทำทุกสิ่งที่คุณต้องการ


hostname: invalid option -- 'l'...
jasonwryan

นั่นคือทุนที่ฉัน ดูเหมือนว่าจะทำงานได้ดีแม้ว่าจะพิมพ์ที่อยู่ IP ของอินเทอร์เฟซทั้งหมด
Joe

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