ฉันจะแก้ไขชื่อโฮสต์เป็นที่อยู่ IP ในสคริปต์ Bash ได้อย่างไร


416

วิธีรัดกุมที่สุดในการแก้ไขชื่อโฮสต์ให้เป็นที่อยู่ IP ในสคริปต์ Bash คืออะไร ฉันใช้Arch ลินุกซ์


21
น่าเสียดายที่getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>คำตอบอยู่ตรงนั้นใกล้ด้านล่าง มันเป็นวิธีที่ง่ายที่สุดไม่ต้องใช้แพคเกจเพิ่มเติมและง่ายต่อการแยกวิเคราะห์จากสคริปต์ Bash
0xC0000022L

1
@ 0xC0000022L: อัปยศใหม่คือคำตอบที่แสดงให้เห็นgetent hosts somehostเมื่อทำงานนี้ในขณะที่somehostจะผลิตที่อยู่ IPv6ซึ่งจะแตกต่างจากวิธีการเครื่องมืออื่น ๆ ส่วนใหญ่ ( ping, sshอย่างน้อย) แก้ไขชื่อและแบ่งบางสิ่งบางอย่าง ใช้แทนahosts hosts
j_random_hacker

@j_random_hacker: ใครกันที่ห้ามไม่ให้คุณร้องขอที่อยู่ IPv4 ( ahostsv4) หรือ IPv6 ( ahostsv6) โดยเฉพาะ โดยส่วนตัวฉันพบว่าไม่มีอะไรผิดปกติกับคำขอที่ไม่เจาะจงซึ่งส่งคืน IPv6 ควรเตรียมรหัสของคุณ IPv6 เปิดให้บริการมาแล้วกว่า 20 ปีแล้ว
0xC0000022L

@ 0xC0000022L: ไม่มีใคร "ทำให้ฉัน" ทำแบบนั้น แต่คำตอบนั้นมีคำแนะนำเป็นhostsพิเศษและจนถึงขณะนี้มี 4 คนที่แสดงความคิดเห็นของ vinc17 ที่แสดงความเจ็บปวดที่เกิดจาก "IPv6" โดยฉับพลัน การเตรียมพร้อมสำหรับ IPv6 นั้นไม่ได้เป็นปัญหาเสมอไป: หลาย ๆ โปรแกรมต้องการวิธีในการพิจารณาว่าชื่อ / ที่อยู่สองรายการอ้างถึงโฮสต์เดียวกันหรือไม่ พวกเขาสามารถใช้การจับคู่สตริงอย่างง่ายหรือต้องรู้มากเกี่ยวกับเครือข่ายเพื่อค้นหาคำตอบ "จริง" หลังเป็นเขตที่วางทุ่นระเบิดโปรแกรมและระบบของบุคคลที่สามมากมายซึ่งฉันไม่สามารถควบคุมได้ - ใช้โปรแกรมเดิม
j_random_hacker

คำตอบ:


533

คุณสามารถใช้getentซึ่งมาพร้อมกับglibc(ดังนั้นคุณเกือบจะมีมันบน Linux) สิ่งนี้จะแก้ไขโดยใช้ gethostbyaddr / gethostbyname2 และดังนั้นจะตรวจสอบ/etc/hosts/ NIS / etc:

getent hosts unix.stackexchange.com | awk '{ print $1 }'

หรือตามที่ Heinzi กล่าวไว้ด้านล่างคุณสามารถใช้digกับ+shortอาร์กิวเมนต์ (สอบถามเซิร์ฟเวอร์ DNS โดยตรงไม่ได้ดู/etc/hosts/ NSS / etc):

dig +short unix.stackexchange.com

หากdig +shortไม่พร้อมใช้งานข้อใดข้อหนึ่งต่อไปนี้ควรใช้งานได้ DNS แบบสอบถามทั้งหมดเหล่านี้โดยตรงและไม่สนใจวิธีการแก้ไขอื่น ๆ :

host unix.stackexchange.com | awk '/has address/ { print $4 }'
nslookup unix.stackexchange.com | awk '/^Address: / { print $2 }'
dig unix.stackexchange.com | awk '/^;; ANSWER SECTION:$/ { getline ; print $5 }'

หากคุณต้องการพิมพ์ IP เพียงรายการเดียวให้เพิ่มexitคำสั่งลงในawkเวิร์กโฟลว์

dig +short unix.stackexchange.com | awk '{ print ; exit }'
getent hosts unix.stackexchange.com | awk '{ print $1 ; exit }'
host unix.stackexchange.com | awk '/has address/ { print $4 ; exit }'
nslookup unix.stackexchange.com | awk '/^Address: / { print $2 ; exit }'
dig unix.stackexchange.com | awk '/^;; ANSWER SECTION:$/ { getline ; print $5 ; exit }'

2
โดยค่าเริ่มต้นการใช้ dig จะทำงานกับ ipv4 เท่านั้นโดยที่ host ให้คำตอบทั้ง ipv4 และ ipv6 สิ่งนี้อาจไม่คาดคิด คุณสามารถลองhost www.google.com, dig +short www.google.com, host ipv6.google.com, dig +short ipv6.google.com, ,host www.facebook.com dig +short www.facebook.com
jfg956

6
DIG ไม่ทำงานหากเป็น CNAME จะไม่ส่งคืน IP
sorin

4
บางครั้งhostสามารถหมดเวลาและไม่ได้รับผลตอบแทนใด ๆ สำหรับบางโดเมนdig +shortอาจส่งคืนชื่อแทนโดเมนในบรรทัดแรก ดังนั้นเพื่อให้มั่นใจว่าการส่งออกเป็นที่อยู่ IPv4 dig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1ใช้
caiguanhao

9
การใช้getent hosts <host>ไม่ถูกต้องเช่นอาจให้ที่อยู่ IPv6 ในขณะที่ IPv6 ไม่ทำงาน ทางออกที่ถูกต้องคือใช้getent ahosts <host>เพื่อลองทั้ง IPv6 และ IPv4 หากจำเป็น
vinc17

5
น่ากล่าวถึง: host, dig และ nslookup ดูเหมือนจะพูดคุยกับเซิร์ฟเวอร์ที่ระบุใน resolv.conf โดยตรงในขณะที่ "getent hosts" ให้ความเคารพทั้งไฟล์ local hosts และการแคชระดับไลบรารี (เช่น nscd) หากเปิดใช้งาน
Saustrup

141

ด้วยhostจากแพคเกจdnsutils :

$ host unix.stackexchange.com
unix.stackexchange.com has address 64.34.119.12

( แก้ไขชื่อแพคเกจตามความคิดเห็นที่เป็นบันทึกการแจกแจงอื่น ๆ มี. hostในแพคเกจที่แตกต่างกัน: Debian / Ubuntu bind9 เจ้าภาพ , openSUSE ผูก-utils , Frugalware ผูก .)


4
คุณหมายถึงdnsutilsหรือเปล่า อย่างไรก็ตามhostทำงานได้ดีขอบคุณ
Eugene Yarmash

คุณอาจพูดถูก ฉันไม่มี Arch ที่นี่เพื่อตรวจสอบ (ตั้งใจที่จะผนวกความคิดเห็นในภายหลังที่กล่าวถึงเรื่องนี้ แต่คำตอบนั้นได้รับการยกระดับขึ้นแล้วดังนั้นฉันจึงควรจับมัน ... )
manatwork

1
ดูรายการแก้ไขปัญหาด้านล่างหากคุณต้องการแก้ไขสิ่งที่ไม่ได้อยู่ใน DNS (เช่น / etc / hosts)
Gavin Brock

2
โปรดทราบว่าhostบางครั้งส่งคืนเอาต์พุตหลายบรรทัด (ในกรณีของการเปลี่ยนเส้นทาง) คุณจะต้องการhost unix.stackexchange.com | tail -n1ถ้าคุณเพียงแค่ต้องการบรรทัดที่มีที่อยู่ IP
Edward Coffey

3
คำตอบนี้สมควรได้รับ downvote อย่างจริงจัง hostเป็นเครื่องมือ DNS (คล้ายกับnslookup) ดังนั้นจึงเพียง แต่ดูโฮสต์ขึ้นใน DNS /etc/hostsไม่ได้อยู่ในเช่น ดังนั้นจึงไม่ใช่คำตอบสำหรับคำถามของ OP
เตอร์

54

ฉันมีเครื่องมือบนเครื่องที่ดูเหมือนจะทำงานได้ man page แสดงว่ามันมาพร้อมกับ mysql ... นี่คือวิธีที่คุณสามารถใช้มัน:

resolveip -s unix.stackexchange.com
64.34.119.12

ค่าที่ส่งคืนของเครื่องมือนี้แตกต่างจาก 0 หากชื่อโฮสต์ไม่สามารถแก้ไขได้:

resolveip -s unix.stackexchange.coma
resolveip: Unable to find hostid for 'unix.stackexchange.coma': host not found
exit 2

อัพเดท บน fedora มาพร้อมกับ mysql-server:

yum provides "*/resolveip"
mysql-server-5.5.10-2.fc15.x86_64 : The MySQL server and related files
Dépôt         : fedora
Correspondance depuis :
Nom de fichier      : /usr/bin/resolveip

ฉันเดาว่ามันจะสร้างการพึ่งพาที่แปลกสำหรับสคริปต์ของคุณ ...


6
นี่น่าจะเป็นทางออกเดียวในที่นี้ที่ใช้บิลด์ของระบบปฏิบัติการในตัวแก้ไข - ดังนั้นจึงเหมาะสำหรับ / etc / hosts รวมถึง DNS
Gavin Brock

8
getentดังรายละเอียดในคำตอบอื่น ๆ ดูที่ / etc / hosts และมาพร้อมกับ glibc ดังนั้นจึงไม่มีการพึ่งพาระบบ Linux
Asfand Qazi

44

การใช้คำสั่งต่อไปนี้digอนุญาตให้คุณอ่านผลลัพธ์โดยตรงโดยไม่ต้องใช้ sed / awk / etc มายากล:

$ dig +short unix.stackexchange.com
64.34.119.12

digรวมอยู่ในdnsutilsแพ็คเกจด้วย


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

hostname=unix.stackexchange.com

ip=`dig +short $hostname`

if [ -n "$ip" ]; then
    echo IP: $ip
else
    echo Could not resolve hostname.
fi

หมายเหตุ 2 : หากชื่อโฮสต์มีที่อยู่ IP หลายรายการ (ลองdebian.orgเป็นต้น) ทั้งหมดจะถูกส่งคืน "ปัญหา" นี้ส่งผลกระทบต่อเครื่องมือทั้งหมดที่กล่าวถึงในคำถามนี้:


2
โปรดทราบว่าหากโดเมนมีรายการ CNAME โดเมนนั้นอาจพิมพ์ในบรรทัดแรกแทนที่อยู่ IP
pcworld

40
getent hosts unix.stackexchange.com | cut -d' ' -f1

4
ยังพิจารณาahosts, ahostsv4, กับahostsv6 getent
0xC0000022L

cutจะไม่ใช้สำหรับการเข้าถึงซึ่งใช้\tเพื่อแยกคอลัมน์ นี่เป็นกรณีของ Solaris
เซเว่น

1
@ceving: บน Solaris คุณอาจต้องเรียกใช้cutโดยไม่มี-d(ค่าเริ่มต้น\tเป็นตัวคั่น) บน Linux มันมีช่องว่างดังนั้นบรรทัดด้านบนจึงใช้งานได้
sborsky

27

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

Chris Down และ Heinzi พูดคุยสั้น ๆ เกี่ยวกับกรณีที่ชื่อโฮสต์แก้ไขเป็นมากกว่าหนึ่งที่อยู่ IP ในกรณีนี้ (และอื่น ๆ ด้านล่าง) การสร้างสคริปต์พื้นฐานภายใต้ข้อสันนิษฐานว่าชื่อโฮสต์สามารถแก้ไขเป็นที่อยู่ IP เดียวได้โดยตรง ด้านล่างตัวอย่างที่มีชื่อโฮสต์จะแปลงเป็นมากกว่าหนึ่งที่อยู่ IP:

$ host www.l.google.com
www.l.google.com has address 209.85.148.147
www.l.google.com has address 209.85.148.103
www.l.google.com has address 209.85.148.99
www.l.google.com has address 209.85.148.106
www.l.google.com has address 209.85.148.105
www.l.google.com has address 209.85.148.104

แต่สิ่งที่เป็นwww.l.google.com? นี่คือที่จะต้องมีการแนะนำกรณีนามแฝง ตรวจสอบตัวอย่างด้านล่าง:

$ host www.google.com
www.google.com is an alias for www.l.google.com.
www.l.google.com has address 74.125.39.103
www.l.google.com has address 74.125.39.147
www.l.google.com has address 74.125.39.105
www.l.google.com has address 74.125.39.99
www.l.google.com has address 74.125.39.106
www.l.google.com has address 74.125.39.104

ดังนั้นwww.google.comไม่ได้แก้ไขโดยตรงไปยังที่อยู่ IP แต่เป็นนามแฝงที่แก้ไขไปยังที่อยู่ IP หลายแห่ง สำหรับข้อมูลเพิ่มเติมเกี่ยวนามแฝงตรวจสอบที่นี่ แน่นอนกรณีที่นามแฝงมีที่อยู่ IP เดียวที่เป็นไปได้ดังที่แสดงด้านล่าง:

$ host g.www.ms.akadns.net
g.www.ms.akadns.net is an alias for lb1.www.ms.akadns.net.
lb1.www.ms.akadns.net has address 207.46.19.190

แต่นามแฝงจะถูกล่ามโซ่? คำตอบคือใช่:

$ host www.microsoft.com
www.microsoft.com is an alias for toggle.www.ms.akadns.net.
toggle.www.ms.akadns.net is an alias for g.www.ms.akadns.net.
g.www.ms.akadns.net is an alias for lb1.www.ms.akadns.net.
lb1.www.ms.akadns.net has address 207.46.19.254

$ host www.google.fr
www.google.fr is an alias for www.google.com.
www.google.com is an alias for www.l.google.com.
www.l.google.com has address 74.125.39.147
www.l.google.com has address 74.125.39.103
www.l.google.com has address 74.125.39.99
www.l.google.com has address 74.125.39.106
www.l.google.com has address 74.125.39.104
www.l.google.com has address 74.125.39.105

ฉันไม่พบตัวอย่างใด ๆ ที่ชื่อโฮสต์แก้ไขเป็นนามแฝงที่ไม่ได้แก้ไขที่อยู่ IP แต่ฉันคิดว่ากรณีอาจเกิดขึ้น

มากกว่าหลายที่อยู่ IP และชื่อแทนมีบางกรณีพิเศษอื่น ๆ ... แล้ว IPv6 ล่ะ? คุณสามารถลอง:

$ host ipv6.google.com
ipv6.google.com is an alias for ipv6.l.google.com.
ipv6.l.google.com has IPv6 address 2a00:1450:8007::68

ที่ชื่อโฮสต์ipv6.google.comเป็นชื่อโฮสต์IPv6 เท่านั้น ชื่อโฮสต์แบบสแต็กคู่:

$ host www.facebook.com
www.facebook.com has address 66.220.153.15
www.facebook.com has IPv6 address 2620:0:1c08:4000:face:b00c::

เกี่ยวกับ IPv6 อีกครั้งหากโฮสต์ของคุณเป็น IPv4 เท่านั้นคุณยังคงสามารถแก้ไขที่อยู่ IPv6 ได้ (ทดสอบบน WinXP IPv4 เท่านั้นและกับ ipv6.google.com คุณสามารถลองใช้งานบน Linux ได้) ในกรณีนี้ความละเอียดประสบความสำเร็จ แต่ ping ล้มเหลวด้วยข้อผิดพลาดที่ไม่รู้จักโฮสต์ นี่อาจเป็นกรณีที่การเขียนสคริปต์ของคุณล้มเหลว

ฉันหวังว่าคำพูดเหล่านั้นมีประโยชน์


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

21

หากต้องการหลีกเลี่ยงปัญหาเกี่ยวกับชื่อแทนและเตรียมที่อยู่ IP เดียวให้พร้อมใช้งานเสมอ:

python -c 'import socket; print socket.gethostbyname("www.example.com")'

ฉันทำฟังก์ชั่นทุบตีเพื่อติดใน bashrc ของฉันจากคำตอบนี้: gist.github.com/brycepg/ba117a37de53906dc8fcc312bd7d5fee
Bryce Guinta

18
ping -q -c 1 -t 1 your_host_here | grep PING | sed -e "s/).*//" | sed -e "s/.*(//"

ทำงานโดยไม่ต้องพึ่งพาระบบอื่น ๆ (และสำหรับโฮสต์ที่ระบุใน / etc / hosts)


2
การใช้ ping คือสิ่งที่ฉันต้องการเนื่องจากฉันต้องการค่าจากไฟล์ hosts แต่รูปแบบ sed แยกได้อย่างถูกต้อง แต่วิธีนี้ทำงานได้ ping -q -c 1 -t 1 your_host_here | grep PING sed -e "s / ^ [^ (] * [(] //" | sed -e "s /ه)เหมือนกัน ** ///"
ManiacZX

1
หากต้องการแก้ไขบางสิ่งบนเครือข่ายในบ้านของฉันเช่น myhostname.local สิ่งนี้ใช้ได้ผลสำหรับฉันนี่คือคำตอบที่ดีที่สุด
Matt Friedman

1
ฉันขอแนะนำสิ่งนี้ด้วย:ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1
Matt Friedman

getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>การทำงานสำหรับการประกาศภายใน/etc/hostsเกินไป ... และก็เครื่องมือไปสู่สำหรับทุกชนิดของฐานข้อมูลของระบบ (กลุ่ม passwd นามแฝงบริการ)
0xC0000022L

17

เรียบง่าย แต่มีประโยชน์:

  1. getent ahostsv4 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
  2. getent ahostsv6 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
  3. getent hosts google.de | head -n 1 | cut -d ' ' -f 1

คำสั่งทั้งหมดจะแก้ไขที่อยู่ IP หากโฮสต์ยังคงอยู่ หากโฮสต์ชี้ไปที่ CNAME ก็จะได้รับ IP ในกรณีนั้น

คำสั่งแรกส่งคืนที่อยู่ IPv4 ที่ได้รับการแก้ไข

คำสั่งที่สองส่งคืนที่อยู่ IPv6 ที่ได้รับการแก้ไข

คำสั่งที่สามจะส่งคืนที่อยู่ที่เจ้าของต้องการซึ่งอาจเป็นที่อยู่ IPv4 หรือ IPv6


โดยง่ายที่สุด และ avilable โดยค่าเริ่มต้น ไม่เช่นhostนั้นต้องติดตั้งของbindutils
michaelbn

7

นี่คือรูปแบบที่แตกต่างกันเล็กน้อยของpingวิธีการที่ใช้ "โฮสต์ที่ไม่รู้จัก" เข้ามาในบัญชี (โดย piping ผ่าน stderr) และใช้trเพื่อหลีกเลี่ยงการใช้sedregexps:

ping -c1 -t1 -W0 www.example.com 2>&1 | tr -d '():' | awk '/^PING/{print $3}'

ในกรณีที่มีความสำคัญในการจับมูลค่าทางออกจากนั้นจะใช้งานได้ดังต่อไปนี้ (แม้ว่าจะดูหรูหราน้อยกว่า):

ping -c1 -t1 -W0 www.example.com &>/dev/null && ping -c1 -t1 -W0 www.example.com 2>&1 | tr -d '():' | awk '/^PING/{print $3}'

ฉันชอบโซลูชันนี้เพราะใช้งานได้โดยไม่ต้องใช้เครื่องมือใด ๆ เพิ่มเติม
Radon8472

7

เพื่อให้คำตอบของ Chris Down สมบูรณ์และตอบสนองต่อข้อคิดเห็นของ jfgagne เกี่ยวกับนามแฝง (อาจถูกล่ามโซ่) นี่เป็นวิธีแก้ปัญหาที่:

  • คำนึงถึงหลาย IP
  • คำนึงถึงนามแฝงอย่างน้อยหนึ่งชื่อ (CNAME)
  • ไม่ค้นหา/etc/hostsไฟล์ (ในกรณีของฉันฉันไม่ต้องการ); เพื่อสอบถามวิธีการแก้ปัญหาหลามของ dbernt สมบูรณ์แบบ)
  • ไม่ใช้ awk / sed

    dig +short www.alias.com  | grep -v "\.$" | head -n 1

ส่งคืนที่อยู่ IP แรกเสมอหรือว่างเปล่าหากไม่ได้รับการแก้ไข กับรุ่นขุด:

    $ dig -v
    DiG 9.8.1-P1

1
ขอบคุณคำตอบอื่น ๆ ถือว่า "dig + short" จะส่งคืนที่อยู่ IP เดียวเสมอ พวกเขาไม่ได้คิดบัญชี CNAME
jamshid

5
 php -r "echo gethostbyname('unix.stackexchange.com');"

ทำงานได้ แต่ต้องติดตั้ง php ในเทอร์มินัลของคุณ
Radon8472

1
จะมีประโยชน์ในภาชนะนักเทียบท่า PHP ทั่วไปที่ "เจ้าภาพ", "ขุด" ฯลฯ จะไม่สามารถใช้ได้
Fabian Schmengler

5

ฉันต้องการเพิ่มสิ่งนี้เป็นความคิดเห็นของ Andrew McGregor Re: ping อย่างไรก็ตามมันจะไม่ให้ฉันดังนั้นฉันต้องเพิ่มนี่เป็นคำตอบอื่น (หากใครบางคนสามารถย้ายมันไปเป็นความคิดเห็นได้อย่าลังเลที่จะ)

นี่เป็นอีกตัวแปรหนึ่งโดยใช้เฉพาะ ping และ grep:

ping -q -c1 -t1 your_host_here | grep -Eo "([0-9]+\.?){4}"

grep -Eสำหรับการแสดงออกปกติขยายและ grep -oเพื่อกลับเฉพาะส่วนที่จับคู่ regexp ตัวเองมองหาหนึ่งหรือหลายหลัก ( [0-9]+) และเลือกจุด ( \.?) สี่ครั้ง ( {4})


4

คุณสามารถใช้host:

hostname=example.org

# strips the IP
IP=$( host ${hostname} | sed -e "s/.*\ //" )

# checks for errors
if [ $? -ne 0 ] ; then
   echo "Error: cannot resolve ${hostname}" 1>&2
   exit 1;
fi

4

นี่เป็นสูตรทุบตีฉันปรุงโดยใช้คำตอบของคนอื่น - ลองก่อน/etc/hostsแล้วกลับไปที่ nslookup:

resolveip(){
    local host="$1"
    if [ -z "$host" ]
    then
        return 1
    else
        local ip=$( getent hosts "$host" | awk '{print $1}' )
        if [ -z "$ip" ] 
        then
            ip=$( dig +short "$host" )
            if [ -z "$ip" ]
            then
                echo "unable to resolve '$host'" >&2 
                return 1
            else
                echo "$ip"
                return 0
            fi
        else
            echo "$ip"
            return 0
        fi
    fi
}

ต้องมีความชัดเจนgetent hostsไม่ได้เป็นเพียงการค้นหาใน / etc / hosts - มันเต็มรูปแบบในการเรียก DNS-คลี่คลายการgethostbyaddr (3)และมันมากไม่น่าจะล้มเหลวในกรณีที่digจะประสบความสำเร็จ ดูหน้าคนสำหรับ getent
Stuart P. Bentley

@ Stuart ถูกต้อง - ฉันได้เรียนรู้อย่างมากมายตั้งแต่เขียนและใช้คำสั่งที่มีประสิทธิภาพมากเกินไป getentยังคงเป็นที่ชื่นชอบของฉันแม้ว่าฉันจะชอบdig +short
RubyTuesdayDONO

4
nmap -sP 192.168.178.0/24|grep YOUR_HOSTNAME|sed -n 's/.*[(]\([0-9\.]*\)[)].*/\1/p'

เป็นวิธีแก้ปัญหาที่ฉันพบโดยไม่มีเซิร์ฟเวอร์ DNS


3

อาจจะไม่รัดกุมที่สุด แต่ดูเหมือนว่าจะแข็งแกร่งและมีประสิทธิภาพ:

# $(get_host_dns_short "google.com")
#
# Outputs the IPv4 IP Address of a hostname, resolved by DNS. Returns 0 if DNS
# responded successfully; 1 otherwise. Will mask error output.
function get_host_dns_short()
{
    (
        set -o pipefail

        host -4 -W1 -t A "$1" 2>/dev/null | awk '/has address/ { print $NF; exit }'
    ) && return 0 || return 1
}

สิ่งนี้จะส่งออก IPv4 IP เดียวรวมทั้งส่งคืน1ในกรณีที่เกิดความล้มเหลวในขณะที่กำบังเอาต์พุต stderr

คุณสามารถใช้สิ่งนี้:

GOOGLE_IP="$(get_host_dns_short "google.com")"
if [[ $? -eq 0 ]]; then
    echo "Google's IP is ${GOOGLE_IP}."
else
    echo "Failed to resolve Google's IP."
fi

IP ของ Google คือ 216.58.192.46

หากคุณต้องการที่อยู่ IPv6 แทนเพียงแทนที่ด้วย-4-6


3

dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'


1
บริบทบางอย่างในแบบที่คำตอบดีขึ้นกว่าสิ่งที่มีอยู่แล้วจะดีมาก นอกจากนี้โปรดเยื้องคำสั่ง 4 ช่องว่าง (เปรียบเทียบกับไวยากรณ์ markdown)
maxschlepzig

2

1 บรรทัดแก้ไขรายการชื่อโฮสต์

for LINE in `cat ~/Desktop/mylist`; do a=$(nslookup $LINE | awk '/^Address: / { print $1 }');  echo $a >> ~/Desktop/ip; done

2

ฉันทำเช่นนี้ตลอดเวลาบน Mac getentของฉันซึ่งไม่ได้มี pingดูเหมือนแฮ็ค ฉันต้องการคำนึง/etc/hostsถึงเช่นกัน

ดังนั้นฉันเขียน wrapper โง่dns.lookupสำหรับคุณที่มี Node.js ติดตั้งเพื่อให้ CLI:

$ npm install -g lookup-hostname
$ lookup google.com
62.243.192.89

โอกาส 60% ของการแตกก่อนที่คุณจะเข้าใกล้การแก้ไข
dotbit

@dotbit คุณช่วยอธิบายได้ไหม? ฉันใช้รายสัปดาห์นี้ตั้งแต่ '17 และไม่เคยมีปัญหาใด ๆ เลย
โทมัสเซ่น

@ เซ่น แต่คุณเป็นคนเดียวที่เคยเช่นเคย ส่วนที่เหลือของเรามักจะเจอ FAIL ของประเภทหนึ่งหรืออื่น ๆ และเสมอ
dotbit

"เช่นเคย"คุณหมายถึงอะไร "พวกเราที่เหลือ"นั่นใครน่ะ? "พบกับ FAIL"คุณเห็นปัญหาอะไรเป็นพิเศษ ฉันอยากรู้.
โทมัสเซ่น

2

การขุดช้าเกินไปการค้นหา nslook เร็วกว่ามาก

nslookup google.com | grep -Po 'Address:\s*[0-9.]+' | tail -1 | sed -e 's/Address:\s*//g'

2

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

ping -a hostname -c 1

จะpingเป็นครั้งหนึ่งโฮสต์และแก้ไขชื่อโฮสต์ที่อยู่ IP

$ ping -a www.google.com -c 1
PING www.google.com (216.58.211.132) 56(84) bytes of data.
64 bytes from arn09s10-in-f4.1e100.net (216.58.211.132): icmp_seq=1 ttl=54 time=1.51 ms

การใช้ ping นั้นดีเพราะทุกคนมี แต่คุณต้องกรอง IP-Part จากเอาท์พุตหากคุณต้องการใช้ในสคริปต์
Radon8472

1

ใช่มีคำตอบมากมายอยู่แล้ว แต่วิธีแก้ปัญหาที่ใช้ Perl นั้นหายไป:

perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com

ในสคริปต์ทุบตีมันสามารถใช้เช่นนี้:

#!/bin/bash
ipaddr=$(perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com)
echo $ipaddr

โมดูลที่ใช้ในที่นี้คือโมดูลหลักดังนั้นควรใช้งานได้ทุกที่โดยไม่ต้องติดตั้งกับ CPAN


perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null สะอาดกว่ามาก แต่ไม่มีใครนอกจากเราสองคนกำลังใช้pörlทุกคนใช้ Pascal Script แน่นอน
dotbit

ที่จริงฉันชอบเห็นข้อความแสดงข้อผิดพลาดหากมีอะไรผิดพลาด Can't call method "addr" on an undefined valueไม่ใช่ข้อผิดพลาดที่ดีที่สุด แต่อาจให้คำแนะนำเกี่ยวกับปัญหา
Slaven Rezic

1
#!/bin/bash

systemd-resolve   RT.com -t A  | awk '{ print $4 ; exit }'
systemd-resolve unix.stackexchange.com -t A --legend=no | awk '{ print $4 ; exit }'

resolveip -s      RT.com
dig       +short  RT.com
host              RT.com | awk '/has address/ { print $4 }'
nslookup          RT.com | awk '/^Address: /  { print $2 }'
ping -q -c 1 -t 1 RT.com | grep PING | sed -e "s/).*//" | sed -e "s/.*(//"

ruby     -rresolv -e      ' print    Resolv.getaddress "RT.com" '
python2  -c 'import socket; print socket.gethostbyname("RT.com")'
perl     -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' RT.com  2>/dev/null
php      -r "echo gethostbyname( 'RT.com' );"

echo        "   all do work for me - take your pick!  "

1
รุ่นทับทิมพิมพ์คำพูดรอบที่อยู่ IP --- อาจจะควรจะนำมาใช้แทนprint p
Slaven Rezic

ขอบคุณ @Slaven Rezic และรู้สึกฟรีเพื่อโหวต จากนั้นอีกครั้งที่นี่ที่ด้านล่างสคริปต์อาจปรากฏให้เห็นได้จริงยิ่งขึ้น ... ;-)
dotbit

-1
host -t a cisco.com

คำสั่งนี้จะแสดงที่อยู่ IP (จะใช้โดเมนซ้ำกับ IP)


-1

นอกจากวิธีการแก้ปัญหาข้างต้นคุณสามารถแปลชื่อโฮสต์หลายชื่อเป็น ip ผ่านสคริปต์ด้านล่างการพึ่งพาเพียงคำสั่ง "ping" ใน core Unix:

getip(){ ping -c 1 -t 1 $1 | head -1 | cut -d ' ' -f 3 | tr -d '()' 2>&1 | tee >> /tmp/result.log & }

getip 'hostname.number1.net'

getip 'hostname.number2.net'

getip 'hostname.number3.net'

getip 'hostname.number4.net'

getip 'hostname.number5.net'

getip 'hostname.number6.net'

getip 'hostname.number7.net'

getip 'hostname.number8.net'
$ cat /tmp/result.log

ABC.DEF.GHI.XY1

ABC.DEF.GHI.XY2

ABC.DEF.GHI.XY3

ABC.DEF.GHI.XY4

ABC.DEF.GHI.XY5

ABC.DEF.GHI.XY6

ABC.DEF.GHI.XY7

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