Utilitas baris perintah Linux untuk menyelesaikan nama host menggunakan / etc / hosts terlebih dahulu

36

Ada beberapa baris perintah utilitas untuk nama tekad host ( host, dig, nslookup), namun mereka semua nameserver digunakan secara eksklusif, sedangkan aplikasi dalam tampilan umum di /etc/hostspertama (menggunakan gethostbyname saya percaya).

Apakah ada utilitas baris perintah untuk menyelesaikan nama host yang berperilaku seperti aplikasi biasa, sehingga mencari /etc/hoststerlebih dahulu dan baru kemudian menanyakan server nama?

(Saya sadar bahwa itu mungkin akan seperti 3 baris c, tapi saya membutuhkannya di dalam skrip shell yang agak portabel.)

Zulan
sumber
Bisakah Anda jelaskan situasi Anda sedikit lagi? Apakah awk '/hostname/ { print $1 }' /etc/hostsmembantu?
quanta
@quanta Sebenarnya solusi saat ini adalah grep / sed magic on / etc / hosts. Saya ingin menjadikannya lebih umum dengan mundur.
Zulan

Jawaban:

56

Ini mudah dicapai dengan getent:

getent hosts 127.0.0.1

getentakan melakukan pencarian untuk semua jenis data yang dikonfigurasi dalam nsswitch.conf.

womble
sumber
Ini adalah alat yang saya gunakan dalam wadah buruh pelabuhan Alpine saya yang tidak memiliki mekanisme lain seperti digatau nslookup.
Bruno Bronosky
26

Salah satu alat yang akan berfungsi adalah getent. Jadi Anda bisa menggunakan getent hosts www.google.com, atau getent hosts localhost. Ini akan mengambil entri dari database seperti yang ditentukan dalam konfigurasi Switch Layanan Nama Anda /etc/nsswitch.conf.

Sakit kepala
sumber
1
Ya, tapi itu tidak akan kembali ke DNS.
slowpoison
Tidak, itu menyelesaikannya dalam urutan nsswitch.conf.
cjc
@slowpoison, Lihatlah konfigurasi nsswitch Anda. Sistem saya memiliki files dnshost, yang berarti / etc / hosts dikonsultasikan dan kemudian resolver DNS. Konfigurasi Anda mungkin berbeda.
Zoredache
@ cjc, ya. Saya rasa saya tidak mencobanya dengan benar.
slowpoison
@Zoredache, saya cukup terkesan getent. Terima kasih atas intro untuk perintah ini.
slowpoison
8

Anda dapat menggunakan pembungkus gethostbyname () (usang) seperti:

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

Atau bungkus getaddrinfo () seperti:

python -c 'import socket;print socket.getaddrinfo("www.google.com","http")[0][4][0]'

Perhatikan bahwa getaddrinfo akan mengembalikan semua instance sebagai daftar. Bagian terakhir dari perintah hanya memilih tupel pertama. Ini juga dapat mengembalikan alamat IPv6.

Mircea Vutcovici
sumber
1
Ini akan berhasil, tetapi sudah usang untuk sementara waktu. Lihat linux.die.net/man/3/gethostbyname .
Kyle Smith
Terima kasih, saya tidak tahu tentang itu. ;)
Mircea Vutcovici
Dapatkan upvote. Tidak ada satu liner semi-portabel lainnya yang diusulkan.
user239558
Seandainya ini bermanfaat bagi siapa pun, saya membuat versi Python 3 dengan beberapa opsi baris perintah: github.com/acdha/unix_tools/blob/master/bin/getaddrinfo
Chris Adams
6

resolveip akan melakukan ini.

Anehnya, itu adalah bagian dari paket mysql-server di RHEL dan Ubuntu.

cjc
sumber
6

Anda dapat menggunakan [bahasa favorit Anda di sini] untuk menulis skrip yang memanggil getnameinfo . Begitulah seharusnya biner (seperti ping) melakukannya, jadi Anda memastikan Anda mendapatkan perlakuan yang sama.

Kyle Smith
sumber
6

Gunakan getent ahosts, misalnya:

$ getent ahosts www.google.com | sed -n 's/ *STREAM.*//p'
216.58.210.196
2a00:1450:4006:803::2004

Anda akan mendapatkan semua alamat IPv4 dan IPv6, melalui resolib glibc (dengan demikian menggunakan yang /etc/hostspertama, seperti yang biasanya dikonfigurasi dalam /etc/nsswitch.conf).

Jangan gunakan getent hosts, karena itu akan memberi Anda alamat IPv6 atau IPv4 (tidak keduanya), dan protokol yang dipilih mungkin bukan salah satu yang tidak berfungsi. Memang, alamat IPv6 umumnya lebih disukai, tetapi di beberapa tempat, data IPv6 difilter (tidak didukung) oleh router.

vinc17
sumber
3

versi baris perintah "gethostbyname" :

#!/usr/bin/perl
use Socket;

$host = shift @ARGV;
die("usage: gethostbyname hostname\n") unless(defined($host));

$packed_ip = gethostbyname($host);

if (defined $packed_ip) {
    $ip_address = inet_ntoa($packed_ip);
    print "$ip_address\n";
    exit 0
} else {
    warn "$host not found\n";
    exit 1
}
Erik Aronesty
sumber
2

Anda bisa benar-benar hacky dan menggunakan arp:

arp -n somehostname | tr -d '()' | awk '{print $2}'

tetapi itu akan sangat jelek sehingga Anda tidak harus melakukan itu.

Paul M.
sumber
2

getent hostsrusak. Itu lebih suka alamat IPv6, gai.confharus dikonfigurasi untuk lebih memilih IPv4 tetapi ....

Perl gethostbynamemenggunakan prioritas di/etc/nsswitch.conf

hosts: files dns

Jadi ini berfungsi seperti getent hostsseharusnya bekerja untuk saya.

Juga:

perl -e 'use Socket; print inet_ntoa(inet_aton("www.google.com")) . "\n";'

harus bekerja.

Jan Wortelboer
sumber
5
Itu tidak rusak, hanya saja tidak menggunakan getaddrinfo (yang bertuliskan /etc/gai.conf). Untuk menggunakan getaddrinfo, jalankan getent ahosts.
craig65535
1

Coba ini:

if [ `grep -c "hostname" /etc/hosts` -ge 1 ]; then
    ip=`awk '/hostname/ { print $1 }' /etc/hosts`
else
    ip=`host hostname | awk '/hostname has address/ { print $4 }'`
fi
kuanta
sumber
-1

Perintah berikut akan melakukan pencarian melalui DNS / etc / hosts melalui pencarian server DNS langsung.

ping -W2 -c1 google.com | grep PING | sed -r "s/^[^\(]*\(([\.0-9]*)\).*/\1/"

Perintah ini akan mencoba melakukan ping domain (dalam hal ini, google.com) sekali dengan waktu tunggu tunggu 2 detik, dapatkan baris pertama dari perintah PING yang akan menyatakan "PING google.com (216.58.199.36) 56 (84 ) byte data ", lalu gunakan Stream Editor (sed) untuk mendeteksi set kurung pertama dan mengekstrak data di dalamnya yang merupakan alamat IP yang kami cari.

CATATAN: ekspresi regex tidak akan berfungsi jika ada tanda kurung (alias kurung bundar) di URL, tetapi ini akan menjadi kasus yang jarang terjadi.

John
sumber