Linux命令行实用程序首先使用/ etc / hosts解析主机名


36

有几个命令行工具来解析主机名(hostdignslookup),但是它们都使用专门的域名服务器,而在一般的外观应用/etc/hosts第一(使用gethostbyname我相信)。

是否有一个命令行实用程序来解析行为类似于普通应用程序的主机名,从而/etc/hosts首先查找然后才询问名称服务器?

(我知道它可能像3行c,但是我需要在一个可移植的shell脚本中使用它。)


您能否再说明一下您的情况?有awk '/hostname/ { print $1 }' /etc/hosts帮助吗?
量子

@quanta实际上,当前的解决方案是/ etc / hosts上的grep / sed magic。我想通过回退使它更通用。
Zulan

Answers:


56

这很容易实现getent

getent hosts 127.0.0.1

getent将针对中配置的任何类型的数据进行查找nsswitch.conf


这是我在没有其他机制(例如dig或)的Alpine docker容器中使用的工具nslookup
布鲁诺·布洛诺斯基

26

一种有效的工具是getent。因此您可以使用getent hosts www.google.comgetent hosts localhost。它将根据名称服务交换器配置中指定的数据库检索条目/etc/nsswitch.conf


1
是的,但是那不会依靠DNS。
slowpoison 2012年

不,它以nsswitch.conf顺序解析。
cjc 2012年

@slowpoison,看看您的nsswitch配置。我的系统有files dns用于主机的主机,这意味着先查询/ etc / hosts,然后再查询DNS解析器。您的配置可能不同。
Zoredache 2012年

@cjc,确实如此。我认为我没有正确尝试。
slowpoison 2012年

@Zoredache,我印象深刻getent。感谢您对该命令的介绍。
slowpoison 2012年

8

您可以使用gethostbyname()(不建议使用)包装,例如:

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

或类似的getaddrinfo()包装器:

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

请注意,getaddrinfo将所有实例作为列表返回。该命令的最后一部分仅选择第一个元组。这也可以返回IPv6地址。


1
这可以工作,但是已经过时了一段时间。参见linux.die.net/man/3/gethostbyname
凯尔·史密斯

谢谢,我对此一无所知。;)
Mircea Vutcovici 2012年

进行投票。没有提出其他半便携式单缸套的建议。
user239558

万一这对其他人有价值,我制作了一个带有一些命令行选项的Python 3版本:github.com/acdha/unix_tools/blob/master/bin/getaddrinfo
Chris Adams

6

resolveip 将做到这一点。

奇怪的是,它是RHEL和Ubuntu上mysql-server软件包的一部分。


6

您可以使用[这里您最喜欢的语言]编写一个调用getnameinfo的脚本。这就是二进制文件(如ping)的处理方式,因此可以确保获得相同的处理。


6

使用getent ahosts,例如:

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

您将通过glibc解析器获取所有IPv4和IPv6地址(因此/etc/hosts,通常使用中的第一个配置/etc/nsswitch.conf)。

不要使用getent hosts,因为它会为您提供IPv6或IPv4地址(不能同时提供两者),并且所选协议可能不是一种无效的协议。确实,IPv6地址通常是首选,但在某些地方,路由器会过滤(不支持)IPv6数据。


3

“ 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

您可能真的很hacky,可以使用arp

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

但这真的很丑,所以您不应该这样做。


2

getent hosts被打破。它更喜欢IPv6地址,gai.conf应该配置为更喜欢ipv4,但是...

Perl在中gethostbyname使用优先级/etc/nsswitch.conf

hosts: files dns

因此,这就像getent hosts应该为我工作。

也:

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

应该管用。


5
它没有坏,只是不使用getaddrinfo(读取/etc/gai.conf)。要使用getaddrinfo,请运行getent ahosts
craig65535

1

尝试这个:

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

以下命令将通过直接DNS服务器查找通过DNS / etc / hosts执行查找。

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

此命令将尝试对域(在这种情况下为google.com)执行一次ping操作,等待超时为2秒,获得PING命令的第一行,该行的内容为“ PING google.com(216.58.199.36)56(84 )数据字节”,然后使用Stream Editor(sed)检测第一组括号并提取其中的数据,这就是我们要查找的IP地址。

注意:如果URL中带有括号(又称圆括号),则regex表达式将不起作用,但是这种情况很少见。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.