Tiện ích dòng lệnh Linux để giải quyết tên máy chủ bằng cách sử dụng / etc / hosts trước


36

Có một số tiện ích dòng lệnh để tên quyết tâm máy chủ ( host, dig, nslookup), tuy nhiên tất cả họ đều sử dụng máy chủ tên riêng, trong khi các ứng dụng trong cái nhìn tổng quát trong /etc/hostsđầu (sử dụng GetHostByName Tôi tin).

Có một tiện ích dòng lệnh để giải quyết các tên máy chủ hoạt động như một ứng dụng thông thường, do đó tìm kiếm /etc/hoststrước và sau đó hỏi một máy chủ tên?

(Tôi biết rằng nó có thể giống như 3 dòng c, nhưng tôi cần nó bên trong một tập lệnh shell di động.)


Bạn có thể vui lòng giải thích tình hình của bạn nhiều hơn một chút? Có awk '/hostname/ { print $1 }' /etc/hostsgiúp được không?
lượng tử

@quanta Trên thực tế, giải pháp hiện tại là grep / sed ma thuật trên / etc / hosts. Tôi muốn làm cho nó chung chung hơn với một dự phòng.
Zulan

Câu trả lời:


56

Điều này có thể dễ dàng đạt được với getent:

getent hosts 127.0.0.1

getentsẽ thực hiện tra cứu cho bất kỳ loại dữ liệu được cấu hình trong nsswitch.conf.


Đây là công cụ tôi sử dụng trong các container docker không có cơ chế nào khác giống như dighoặc nslookup.
Bruno Bronosky

26

Một công cụ sẽ làm việc là getent. Vì vậy, bạn có thể sử dụng getent hosts www.google.com, hoặc getent hosts localhost. Nó sẽ lấy các mục từ cơ sở dữ liệu như được chỉ định trong cấu hình Chuyển đổi dịch vụ tên của bạn /etc/nsswitch.conf.


1
Có, nhưng điều đó sẽ không rơi vào DNS.
Slowpoison

Không, nó giải quyết nó theo thứ tự nsswitch.conf.
cjc

@slowpoison, Hãy xem cấu hình nsswitch của bạn. Hệ thống của tôi có files dnscác máy chủ, có nghĩa là / etc / hosts được tư vấn và sau đó là trình phân giải DNS. Cấu hình của bạn có thể khác nhau.
Zoredache

@cjc, nó làm. Tôi không nghĩ rằng tôi đã thử nó một cách chính xác.
Slowpoison

@Zoredache, tôi khá ấn tượng với getent. Cảm ơn đã giới thiệu lệnh này.
Slowpoison

8

Bạn có thể sử dụng trình bao bọc gethostbyname () (không dùng nữa) như:

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

Hoặc một trình bao bọc getaddrinfo () như:

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

Lưu ý rằng getaddrinfo sẽ trả về tất cả các trường hợp dưới dạng danh sách. Phần cuối của lệnh chỉ chọn bộ dữ liệu đầu tiên. Điều này cũng có thể trả về địa chỉ IPv6.


1
Điều này sẽ hoạt động, nhưng nó đã lỗi thời trong một thời gian. Xem linux.die.net/man/3/gethostbyname .
Kyle Smith

Cảm ơn bạn, tôi không biết về nó. ;)
Mircea Vutcovici

Có một upvote. Không có một lớp lót bán di động khác đã được đề xuất.
user239558

Trong trường hợp điều này có giá trị với bất kỳ ai khác, tôi đã tạo phiên bản Python 3 với một vài tùy chọn dòng lệnh: github.com/acdha/unix_tools/blob/master/bin/getaddrinfo
Chris Adams

6

resolveip sẽ làm điều này

Điều kỳ lạ, đó là một phần của các gói máy chủ mysql trên RHEL và Ubuntu.


6

Bạn có thể sử dụng [ngôn ngữ yêu thích của bạn ở đây] để viết một tập lệnh gọi getnameinfo . Đó là cách các tệp nhị phân (như ping) nên được thực hiện, vì vậy bạn đảm bảo bạn sẽ có được sự đối xử tương tự.


6

Sử dụng getent ahosts, ví dụ:

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

Bạn sẽ nhận được tất cả các địa chỉ IPv4 và IPv6, thông qua trình phân giải glibc (do đó sử dụng /etc/hoststrước, như thường được định cấu hình /etc/nsswitch.conf).

Không sử dụng getent hosts, vì nó sẽ cung cấp cho bạn địa chỉ IPv6 hoặc IPv4 (không phải cả hai) và giao thức được chọn có thể không phải là giao thức không hoạt động. Thật vậy, địa chỉ IPv6 thường được ưa thích, nhưng tại một số nơi, dữ liệu IPv6 được lọc (không được hỗ trợ) bởi các bộ định tuyến.


3

Phiên bản dòng lệnh "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

Bạn có thể thực sự hack và sử dụng arp:

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

nhưng điều đó sẽ thực sự xấu xí vì vậy bạn không nên làm điều đó.


2

getent hostsbị phá vỡ. Nó thích địa chỉ IPv6, gai.confnên được cấu hình để thích ipv4 nhưng ....

Perl gethostbynamesử dụng quyền ưu tiên trong/etc/nsswitch.conf

hosts: files dns

Vì vậy, điều này làm việc như getent hostsnên làm việc cho tôi.

Cũng thế:

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

nên làm việc.


5
Nó không bị hỏng, nó chỉ không sử dụng getaddrinfo (đọc /etc/gai.conf). Để sử dụng getaddrinfo, hãy chạy getent ahosts.
craig65535

1

Thử đi:

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

Lệnh sau sẽ thực hiện tra cứu qua DNS / etc / hosts qua tra cứu máy chủ DNS trực tiếp.

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

Lệnh này sẽ cố gắng ping một tên miền (trong trường hợp này là google.com) một lần với thời gian chờ là 2 giây, nhận dòng đầu tiên của lệnh PING sẽ ghi "PING google.com (216.58.199.36) 56 (84 ) byte dữ liệu ", sau đó sử dụng Stream Editor (sed) để phát hiện bộ dấu ngoặc đầu tiên và trích xuất dữ liệu trong đó là địa chỉ IP mà chúng tôi đang tìm kiếm.

LƯU Ý: biểu thức regex sẽ không hoạt động nếu có dấu ngoặc đơn (còn gọi là dấu ngoặc tròn) trong URL, nhưng đây sẽ là trường hợp hiếm gặp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.