Apa cara paling ringkas untuk menyelesaikan nama host ke alamat IP dalam skrip Bash? Saya menggunakan Arch Linux .
linux
bash
networking
dns
Eugene Yarmash
sumber
sumber
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
jawabannya ada di suatu tempat di dekat bagian bawah. Ini adalah yang paling sederhana, tidak memerlukan paket tambahan dan lebih mudah untuk diuraikan dari skrip Bash juga.getent hosts somehost
, ketika menjalankan ini sementarasomehost
akan menghasilkan alamat IPv6 , yang berbeda dari bagaimana sebagian besar alat lain (ping
,ssh
setidaknya) menyelesaikan nama, dan merusak beberapa hal. Gunakanahosts
bukanhosts
.ahostsv4
) atau IPv6 (ahostsv6
)? Secara pribadi saya tidak menemukan kesalahan dengan permintaan tidak spesifik untuk mengembalikan IPv6. Kode Anda harus disiapkan. IPv6 telah ada selama lebih dari 20 tahun sekarang.hosts
, dan sejauh ini 4 orang telah meningkatkan komentar vinc17 yang mengungkapkan rasa sakit yang disebabkan oleh "tiba-tiba IPv6". Bersiap untuk IPv6 tidak selalu menjadi masalah: banyak program membutuhkan cara untuk menentukan apakah dua nama / alamat merujuk ke host yang sama. Mereka dapat menggunakan pencocokan string sederhana, atau mereka harus tahu banyak tentang jaringan untuk menemukan jawaban "benar". Yang terakhir adalah ladang ranjau, begitu banyak program dan sistem pihak ke-3 - yang saya tidak punya kendali atas - menggunakan yang pertama.Jawaban:
Anda dapat menggunakan
getent
, yang datang denganglibc
(sehingga Anda hampir pasti memilikinya di Linux). Ini diselesaikan menggunakan gethostbyaddr / gethostbyname2, dan juga akan memeriksa/etc/hosts
/ NIS / etc:Atau, seperti yang dikatakan Heinzi di bawah ini, Anda dapat menggunakan argumen (
dig
meminta+short
server DNS secara langsung, tidak melihat/etc/hosts
/ NSS / etc):Jika
dig +short
tidak tersedia, salah satu dari yang berikut ini akan berfungsi. Semua DNS permintaan ini secara langsung dan mengabaikan cara resolusi lain:Jika Anda hanya ingin mencetak satu IP, tambahkan
exit
perintah keawk
alur kerja.sumber
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
.host
waktu habis dan tidak menghasilkan apa-apa. Untuk beberapa domain,dig +short
dapat mengembalikan alias domain di baris pertama. Jadi, untuk memastikan outputnya adalah alamat IPv4, gunakandig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1
.getent hosts <host>
tidak benar, karena misalnya ia dapat memberikan alamat IPv6 sementara IPv6 tidak berfungsi. Solusi yang benar adalah menggunakangetent ahosts <host>
untuk mencoba IPv6 dan IPv4 jika diperlukan.Dengan
host
dari paket dnsutils :( Nama paket terkoreksi sesuai komentar. Sebagai catatan distribusi lain memiliki
host
dalam paket yang berbeda: Debian / Ubuntu bind9-host , openSUSE bind-utils , Frugalware bind .)sumber
host
bekerja dengan baik, terima kasihhost
kadang - kadang mengembalikan output multi-line (dalam kasus pengalihan), Anda akan inginhost unix.stackexchange.com | tail -n1
jika Anda hanya ingin baris dengan alamat IP.host
adalah alat DNS (mirip dengannslookup
) sehingga hanya mencari host di DNS, bukan di mis/etc/hosts
. Jadi ini BUKAN jawaban untuk pertanyaan OP.Saya memiliki alat di mesin saya yang tampaknya melakukan pekerjaan itu. Halaman manual menunjukkan tampaknya datang dengan mysql ... Ini adalah bagaimana Anda dapat menggunakannya:
Nilai pengembalian alat ini berbeda dari 0 jika nama host tidak dapat diselesaikan:
PEMBARUAN Pada fedora, ia datang dengan server mysql:
Saya kira itu akan membuat ketergantungan aneh untuk skrip Anda ...
sumber
getent
, sebagaimana dirinci dalam jawaban lain, juga melihat / etc / hosts, dan dilengkapi dengan glibc, sehingga tidak memiliki dependensi pada sistem Linux.Perintah berikut menggunakan
dig
memungkinkan Anda untuk membaca hasilnya secara langsung tanpa sed / awk / etc. sihir:dig
juga termasuk dalamdnsutils
paket.Catatan :
dig
memiliki nilai balik0
, meskipun nama tidak dapat diselesaikan. Dengan demikian, Anda perlu memeriksa apakah output kosong daripada memeriksa nilai kembali:Catatan 2 : Jika nama host memiliki beberapa alamat IP (coba
debian.org
, misalnya), semuanya akan dikembalikan. "Masalah" ini memengaruhi semua alat yang disebutkan dalam pertanyaan ini sejauh ini:sumber
sumber
ahosts
,ahostsv4
,ahostsv6
dengangetent
.cut
tidak akan untuk getent, yang digunakan\t
untuk memisahkan kolom. Ini adalah kasus di Solaris.cut
tanpa-d
(default\t
sebagai pembatas). Di Linux itu spasi, jadi baris di atas berfungsi.Solusi yang diberikan sejauh ini sebagian besar berfungsi dalam kasus yang lebih sederhana: nama host langsung diselesaikan ke satu alamat IPv4. Ini mungkin satu-satunya kasus di mana Anda perlu menyelesaikan nama host, tetapi jika tidak, di bawah ini adalah diskusi tentang beberapa kasus yang mungkin perlu Anda tangani.
Chris Down dan Heinzi secara singkat membahas kasus di mana nama host diputuskan untuk lebih dari satu alamat IP. Dalam hal ini (dan yang lainnya di bawah), skrip dasar dengan asumsi bahwa nama host secara langsung memutuskan ke satu alamat IP mungkin rusak. Di bawah ini, contoh dengan nama host yang diselesaikan lebih dari satu alamat IP:
Tapi apa itu
www.l.google.com
? Di sinilah kasus alias perlu diperkenalkan. Mari kita periksa contoh di bawah ini:Jadi
www.google.com
tidak langsung menyelesaikan ke alamat IP, tetapi ke alias yang itu sendiri memutuskan untuk beberapa alamat IP. Untuk informasi lebih lanjut tentang alias, periksa di sini . Tentu saja, kasus di mana alias memiliki alamat IP tunggal dimungkinkan, seperti yang ditunjukkan di bawah ini:Tapi bisakah alias dirantai? Jawabannya iya:
Saya tidak menemukan contoh di mana nama host diselesaikan ke alias yang tidak menyelesaikan ke alamat IP, tapi saya pikir kasusnya mungkin terjadi.
Lebih dari beberapa alamat IP dan alias, apakah ada beberapa kasus khusus lainnya ... bagaimana dengan IPv6? Kamu bisa mencoba:
Di mana nama host
ipv6.google.com
adalah nama host khusus IPv6. Bagaimana dengan tumpukan ganda nama host:Lagi tentang IPv6, jika host Anda hanya IPv4, Anda masih dapat menyelesaikan alamat IPv6 (diuji pada IPv4 hanya WinXP dan dengan ipv6.google.com, Anda dapat mencobanya di Linux). Dalam hal ini, resolusi berhasil, tetapi ping gagal dengan pesan kesalahan host yang tidak dikenal . Ini mungkin merupakan kasus di mana skrip Anda gagal.
Saya harap komentar itu bermanfaat.
sumber
host
bahkan tidak menyatakan "memiliki alamat" untuk kotak saya.Untuk menghindari masalah dengan alias dan selalu mendapatkan satu alamat IP yang siap digunakan:
sumber
bekerja tanpa ketergantungan pada sistem lain (dan untuk host yang ditentukan di / etc / hosts)
sumber
ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
bekerja untuk deklarasi di dalam/etc/hosts
, juga ... dan itu yang alat go-to-untuk semua jenis sistem database (passwd, kelompok, alias, jasa).Sederhana namun bermanfaat:
getent ahostsv4 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent ahostsv6 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent hosts google.de | head -n 1 | cut -d ' ' -f 1
Semua perintah akan menyelesaikan alamat IP jika host masih ada. Jika host menunjuk ke CNAME, ia juga akan mendapatkan IP dalam kasus itu.
Perintah pertama mengembalikan alamat IPv4 yang diselesaikan
Perintah kedua mengembalikan alamat IPv6 yang diselesaikan
Perintah ketiga akan mengembalikan alamat yang diinginkan pemilik apa yang mungkin alamat IPv4 atau IPv6.
sumber
host
itu memerlukan instalasibindutils
Berikut adalah sedikit variasi dari
ping
pendekatan yang memperhitungkan "host tidak dikenal" ke dalam perhitungan (dengan menyalurkan melalui stderr) dan menggunakantr
untuk menghindari penggunaansed
regexps:Jika penting untuk menangkap nilai keluar, maka yang berikut ini akan berfungsi (meskipun kurang elegan):
sumber
Untuk melengkapi jawaban Chris Down, dan menanggapi komentar jfgagne tentang alias (mungkin dirantai), berikut adalah solusi yang:
/etc/hosts
file (dalam kasus saya, saya tidak menginginkannya); untuk menanyakannya, solusi python dbernt sempurna)tidak menggunakan awk / sed
Selalu kembalikan alamat IP pertama, atau kosongkan tring jika tidak diselesaikan. dengan versi menggali:
sumber
sumber
Saya ingin menambahkan ini sebagai komentar untuk Andrew McGregor Re: ping. Namun itu tidak membiarkan saya, jadi saya perlu menambahkan ini sebagai jawaban lain. (Jika seseorang dapat memindahkannya ke dalam komentar, silakan saja.)
Ini adalah varian lain, hanya menggunakan ping dan grep:
grep -E
untuk ekspresi reguler yang diperluas dangrep -o
hanya mengembalikan bagian yang cocok. regexp itu sendiri mencari satu atau beberapa digit ([0-9]+
) dan secara opsional sebuah titik (\.?
) empat kali ({4}
)sumber
Anda bisa menggunakan
host
:sumber
inilah resep Bash yang saya buat menggunakan jawaban orang lain - pertama kali mencoba
/etc/hosts
, lalu kembali ke nslookup:sumber
getent hosts
bukan hanya pencarian di / etc / hosts - ini adalah panggilan penyelesaian DNS penuh untuk gethostbyaddr (3) , dan sangat kecil kemungkinannya gagal dalam kasus di manadig
akan berhasil. Lihat halaman manual untuk mendapatkan .getent
tetap menjadi favorit saya, meskipun saya juga sukadig +short
adalah solusi yang saya temukan tanpa server DNS
sumber
Mungkin bukan yang paling ringkas, tetapi tampaknya kuat dan efisien:
Ini akan menampilkan IP IPv4 tunggal, serta mengembalikan
1
jika terjadi kegagalan, sambil menyembunyikan keluaran stderr.Anda bisa menggunakannya seperti ini:
Jika Anda menginginkan alamat IPv6, cukup ganti
-4
dengan-6
.sumber
dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'
sumber
1 baris menyelesaikan daftar nama host
sumber
Saya melakukan ini sepanjang waktu di Mac saya yang tidak memiliki
getent
.ping
Sepertinya hack. Saya ingin/etc/hosts
mempertimbangkan juga.Jadi, saya menulis bungkus bodoh
dns.lookup
untuk Anda yang memiliki Node.js terinstal untuk memberikan CLI:sumber
penggalian terlalu lambat, nslookup jauh lebih cepat
sumber
Saya tidak tahu cara termudah untuk bash-script tetapi jika Anda ingin menyelesaikan nama host dan melihat apakah host sudah habis, gunakan
ping
!Apakah
ping
tuan rumah satu kali dan menyelesaikan nama host ke alamat IP.sumber
Ya, sudah ada banyak jawaban, tetapi solusi menggunakan perl tidak ada:
Dalam skrip bash dapat digunakan seperti ini:
Modul yang digunakan di sini adalah modul inti, jadi harus tersedia di mana saja tanpa menginstal dengan CPAN.
sumber
perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null
jauh lebih bersih. tapi tidak seorang pun selain kami berdua yang menggunakan pörl, semua orang tentu saja menggunakan Pascal Script.Can't call method "addr" on an undefined value
bukan pesan kesalahan terbaik, tetapi dapat memberikan petunjuk tentang masalah tersebut.sumber
print
sebaiknya digunakan sebagai gantip
.perintah ini akan menampilkan alamat ip (akan menyimpan domain ke IP)
sumber
Selain solusi di atas, Anda dapat menerjemahkan beberapa nama host ke ip melalui skrip di bawah ini, satu-satunya ketergantungan adalah perintah "ping" di core Unix:
sumber