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.)


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.


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.


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.


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.


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.


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.


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
}

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.


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.


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

-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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.