Utilitário de linha de comando do Linux para resolver nomes de host usando / etc / hosts primeiro


36

Existem vários utilitários de linha de comando para nomes de host resolve ( host, dig, nslookup), no entanto, todos os servidores de nomes de uso exclusivamente, enquanto as aplicações em aparência geral em /etc/hostsprimeiro (utilizando gethostbyname eu acredito).

Existe um utilitário de linha de comando para resolver nomes de host que se comportam como um aplicativo comum, analisando /etc/hostsprimeiro e somente solicitando um servidor de nomes?

(Estou ciente de que provavelmente seria como 3 linhas de c, mas preciso dele dentro de um script shell um tanto portátil.)


Poderia, por favor, explicar um pouco mais a sua situação? Será que awk '/hostname/ { print $1 }' /etc/hostsajuda?
quanta

@quanta Na verdade, a solução atual é grep / sed magic em / etc / hosts. Eu queria tornar isso mais geral com um recuo.
Zulan 22/08/11

Respostas:


56

Isso é facilmente alcançado com getent:

getent hosts 127.0.0.1

getentfará pesquisas para qualquer tipo de dados configurado no nsswitch.conf.


Essa é a ferramenta que eu uso nos meus contêineres Alpine Docker que não possuem outro mecanismo como digou nslookup.
Bruno311 # Bruno Bronosky

26

Uma ferramenta que funcionaria é getent. Então você pode usar getent hosts www.google.com, ou getent hosts localhost. Ele recuperará entradas dos bancos de dados, conforme especificado na sua configuração do Name Service Switch /etc/nsswitch.conf.


1
Sim, mas isso não recairia no DNS.
slowpoison

Não, ele resolve na ordem nsswitch.conf.
CJC

@slowpoison, dê uma olhada na sua configuração nsswitch. Meu sistema tem files dnspara hosts, o que significa que / etc / hosts é consultado e, em seguida, o resolvedor de DNS. Sua configuração pode ser diferente.
Zoredache

@cjc, ele faz. Eu não acho que tentei corretamente.
slowpoison

@ Zoredache, estou bastante impressionado getent. Obrigado pela introdução deste comando.
slowpoison

8

Você pode usar um wrapper gethostbyname () (descontinuado) como:

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

Ou um wrapper getaddrinfo () como:

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

Observe que getaddrinfo retornará todas as instâncias como uma lista. A última parte do comando seleciona apenas a primeira tupla. Isso também pode retornar endereços IPv6.


1
Isso funcionará, mas está obsoleto há um tempo. Veja linux.die.net/man/3/gethostbyname .
Kyle Smith

Obrigado, eu não sabia disso. ;)
Mircea Vutcovici

Tenha um voto positivo. Nenhum outro liner semi-portátil foi proposto.
user239558

Caso isso seja de valor para qualquer outra pessoa, criei
Chris Adams

6

resolveip vai fazer isso.

Estranhamente, faz parte dos pacotes mysql-server no RHEL e Ubuntu.


6

Você pode usar [seu idioma favorito aqui] para escrever um script que chama getnameinfo . É assim que os binários (como ping) devem fazer isso, para garantir que você receba o mesmo tratamento.


6

Use getent ahosts, por exemplo:

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

Você obterá todos os endereços IPv4 e IPv6, através do resolvedor glibc (usando assim /etc/hostsprimeiro, como geralmente configurado em /etc/nsswitch.conf).

Não use getent hosts, pois ele fornecerá endereços IPv6 ou IPv4 (não ambos), e o protocolo escolhido pode não ser aquele que não funciona. De fato, os endereços IPv6 são geralmente preferidos, mas em alguns locais, os dados IPv6 são filtrados (não suportados) pelos roteadores.


3

Versão da linha de comandos "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

Você pode ser realmente hacky e usar arp:

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

mas seria muito feio, então você não deve fazer isso.


2

getent hostsestá quebrado. Prefere endereços IPv6, gai.confdeve ser configurado para preferir o ipv4, mas ....

O Perl gethostbynameusa a precedência em/etc/nsswitch.conf

hosts: files dns

Então, isso funciona como getent hostsdeve funcionar para mim.

Além disso:

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

Deveria trabalhar.


5
Não está quebrado, apenas não usa getaddrinfo (que lê /etc/gai.conf). Para usar o getaddrinfo, execute getent ahosts.
craig65535

1

Tente o seguinte:

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

O comando a seguir executará a pesquisa via DNS / etc / hosts na pesquisa direta do servidor DNS.

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

Este comando tentará executar ping em um domínio (neste caso, google.com) uma vez com um tempo limite de espera de 2 segundos, obter a primeira linha do comando PING que indicará "PING google.com (216.58.199.36) 56 (84 ) bytes de dados ", use o Editor de Stream (sed) para detectar o primeiro conjunto de colchetes e extrair os dados nele, que é o endereço IP que estamos procurando.

NOTA: a expressão regex não funcionará se houver parênteses (também conhecido como colchetes circulares) na URL, mas esse seria um caso raro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.