Qual é a maneira mais concisa de resolver um nome de host para um endereço IP em um script Bash? Estou usando o Arch Linux .
linux
bash
networking
dns
Eugene Yarmash
fonte
fonte
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
resposta esteja em algum lugar lá embaixo, perto do fundo. É o mais simples, não requer pacotes extras e é mais fácil analisar também a partir de um script Bash.getent hosts somehost
, quando executar este enquanto emsomehost
produzirá um endereço IPv6 , que é diferente de como a maioria das outras ferramentas (ping
,ssh
pelo menos) resolver nomes, e quebra algumas coisas. Use o emahosts
vez dehosts
.ahostsv4
) ou IPv6 (ahostsv6
)? Pessoalmente, não encontro nada errado com a solicitação inespecífica que retorna o IPv6. Seu código deve estar preparado. O IPv6 está presente há mais de 20 anos.hosts
, e até agora 4 pessoas votaram positivamente no comentário do vinc17 expressando a dor causada pelo "repente IPv6". Estar preparado para o IPv6 nem sempre é o problema: muitos programas precisam de uma maneira de determinar se dois nomes / endereços se referem ao mesmo host. Eles podem usar a correspondência simples de cadeias de caracteres ou precisam saber muito sobre a rede para encontrar a resposta "verdadeira". O último é um campo minado, tantos programas e sistemas de terceiros - que eu não tenho controle - usam o primeiro.Respostas:
Você pode usar o
getent
que vem comglibc
(então você quase certamente o possui no Linux). Isso resolve usando gethostbyaddr / gethostbyname2 e também verifica/etc/hosts
/ NIS / etc:Ou, como Heinzi disse abaixo, você pode usar
dig
o+short
argumento (consulta diretamente os servidores DNS, não consulta/etc/hosts
/ NSS / etc):Se
dig +short
não estiver disponível, qualquer um dos seguintes deve funcionar. Todos eles consultam o DNS diretamente e ignoram outros meios de resolução:Se você deseja imprimir apenas um IP, adicione o
exit
comando aoawk
fluxo de trabalho do.fonte
host www.google.com
,dig +short www.google.com
,host ipv6.google.com
,dig +short ipv6.google.com
,host www.facebook.com
,dig +short www.facebook.com
.host
pode ser atingido o tempo limite e não retorna nada. Para alguns domínios,dig +short
pode retornar o alias do domínio na primeira linha. Portanto, para garantir que a saída seja um endereço IPv4, usedig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1
.getent hosts <host>
está incorreto, pois, por exemplo, ele pode fornecer um endereço IPv6 enquanto o IPv6 não funciona. A solução correta é usargetent ahosts <host>
para tentar o IPv6 e o IPv4, se necessário.Com
host
o pacote dnsutils :( Nome do pacote corrigido de acordo com os comentários. Como nota, outras distribuições têm
host
em pacotes diferentes: Deb9 / Ubuntu bind9-host , openSUSE bind-utils , Frugalware bind .)fonte
host
funcionou bem, obrigadohost
às vezes retorna saída com várias linhas (no caso de redirecionamentos), você desejaráhost unix.stackexchange.com | tail -n1
se quiser apenas a linha com o endereço IP.host
é uma ferramenta de DNS (semelhante anslookup
), portanto, apenas procura hosts no DNS, não no por exemplo/etc/hosts
. Portanto, NÃO é uma resposta para a pergunta do OP.Eu tenho uma ferramenta na minha máquina que parece fazer o trabalho. A página de manual mostra que parece vir com o mysql ... Aqui está como você pode usá-lo:
O valor de retorno desta ferramenta é diferente de 0 se o nome do host não puder ser resolvido:
ATUALIZAÇÃO No fedora, ele vem com o mysql-server:
Eu acho que isso criaria uma dependência estranha para o seu script ...
fonte
getent
, conforme detalhado na outra resposta, também examina o / etc / hosts e vem com o glibc, portanto não possui dependências em um sistema Linux.O seguinte comando usando
dig
permite ler o resultado diretamente, sem nenhum sed / awk / etc. Magia:dig
também está incluído nodnsutils
pacote.Nota :
dig
tem um valor de retorno igual a0
, mesmo que o nome não possa ser resolvido. Portanto, você precisa verificar se a saída está vazia em vez de verificar o valor de retorno:Nota 2 : Se um nome de host tiver vários endereços IP (tente
debian.org
, por exemplo), todos eles serão retornados. Esse "problema" afeta todas as ferramentas mencionadas nesta pergunta até o momento:fonte
fonte
ahosts
,ahostsv4
,ahostsv6
comgetent
.cut
não será para getent's, que usam\t
para separar colunas. É o caso do Solaris.cut
sem-d
(o padrão\t
é delimitador). No Linux são espaços, portanto a linha acima funciona.As soluções fornecidas até agora funcionam principalmente no caso mais simples: o nome do host é resolvido diretamente para um único endereço IPv4. Este pode ser o único caso em que você precisa resolver nomes de host, mas, se não, a seguir, há uma discussão sobre alguns casos com os quais você pode precisar lidar.
Chris Down e Heinzi discutiram brevemente o caso em que o nome do host resolve para mais de um endereço IP. Nesse caso (e outros abaixo), os scripts básicos sob a suposição de que um nome de host seja resolvido diretamente para um único endereço IP podem ser interrompidos. Abaixo, um exemplo com um nome de host resolvido para mais de um único endereço IP:
Mas o que é isso
www.l.google.com
? É aqui que o caso do alias precisa ser introduzido. Vamos verificar o exemplo abaixo:Portanto
www.google.com
, não resolve diretamente para endereços IP, mas para um alias que resolve sozinho para vários endereços IP. Para mais informações sobre aliases, clique aqui . Obviamente, o caso em que um alias tem um único endereço IP é possível, como mostrado abaixo:Mas os aliases podem ser encadeados? A resposta é sim:
Não encontrei nenhum exemplo em que um nome de host resolva um alias que não seja um endereço IP, mas acho que o caso pode ocorrer.
Mais do que vários endereços IP e apelidos, existem outros casos especiais ... e o IPv6? Você poderia tentar:
Onde o nome do host
ipv6.google.com
é um nome de host somente para IPv6. E os nomes de host de pilha dupla:Novamente sobre o IPv6, se o seu host for apenas IPv4, você ainda poderá resolver os endereços IPv6 (testado em um WinXP somente para IPv4 e com o ipv6.google.com, você poderá experimentá-lo no Linux). Nesse caso, a resolução é bem-sucedida, mas um ping falha com uma mensagem de erro desconhecida do host . Pode ser um caso em que seu script falha.
Espero que essas observações tenham sido úteis.
fonte
host
nem afirma "tem endereço" para minhas caixas.Para evitar o problema com aliases e sempre prepare um único endereço IP para uso:
fonte
funciona sem dependências em outros sistemas (e para hosts especificados em / etc / hosts)
fonte
ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
também funciona para declarações internas/etc/hosts
... e é a ferramenta ideal para todos os tipos de bancos de dados do sistema (passwd, group, aliases, services).Simples, mas útil:
getent ahostsv4 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent ahostsv6 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent hosts google.de | head -n 1 | cut -d ' ' -f 1
Todos os comandos resolverão um endereço IP se o host ainda existir. Se o host apontar para CNAME, ele também obterá o IP nesse caso.
O primeiro comando retorna o endereço IPv4 resolvido
O segundo comando retorna o endereço IPv6 resolvido
O terceiro comando retornará o endereço preferido dos proprietários, o que pode ser endereçado por IPv4 ou IPv6.
fonte
host
que exigem a instalação dobindutils
Aqui está uma pequena variação da
ping
abordagem que leva em consideração "host desconhecido" (canalizando pelo stderr) e usatr
para evitar o uso desed
regexps:Caso seja importante capturar o valor de saída, o seguinte funcionará (embora menos elegante):
fonte
Para concluir a resposta de Chris Down e abordar os comentários do jfgagne sobre aliases (possivelmente encadeados), aqui está uma solução que:
/etc/hosts
arquivo (no meu caso eu não o queria); para consultá-lo, a solução python do dbernt é perfeita)não usa awk / sed
Sempre retorna o primeiro endereço IP ou tring vazio, se não for resolvido. com a versão do dig:
fonte
fonte
Gostaria de adicionar isso como um comentário a Andrew McGregor Re: ping. No entanto, não me deixou, por isso preciso adicionar isso como outra resposta. (Se alguém puder colocá-lo em um comentário, sinta-se à vontade.)
Esta é outra variante, apenas usando ping e grep:
grep -E
para expressão regular estendida egrep -o
retornar apenas a parte correspondente. o próprio regexp procura um ou vários dígitos ([0-9]+
) e, opcionalmente, um ponto (\.?
) quatro vezes ({4}
)fonte
Você poderia usar
host
:fonte
aqui está uma receita do Bash que preparei usando as respostas de outras pessoas - primeiro tente
/etc/hosts
e depois volte ao nslookup:fonte
getent hosts
não é apenas uma pesquisa em / etc / hosts - é uma chamada completa de resolução de DNS para gethostbyaddr (3) , e é muito improvável que falhe em um caso dedig
sucesso. Veja a página de manual para getent .getent
permanece o meu favorito, embora eu também gostodig +short
foi a solução que encontrei sem o servidor DNS
fonte
Talvez não seja o mais conciso, mas parece ser robusto e eficiente:
Isso produzirá um único IPv4 IP, além de retornar
1
em caso de falha, mascarando a saída stderr.Você pode usá-lo assim:
Se você deseja um endereço IPv6, substitua-o
-4
por-6
.fonte
dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'
fonte
1 linha resolve uma lista de nome de host
fonte
Estou fazendo isso o tempo todo no meu Mac, que não possui
getent
.ping
parece um hack. Eu também gostaria de levar/etc/hosts
em consideração.Então, escrevi um invólucro estúpido
dns.lookup
para você que possui o Node.js instalado para fornecer uma CLI:fonte
escavação é muito lenta, nslookup é muito mais rápido
fonte
Não sei a maneira mais fácil para um script bash, mas se você quiser resolver um nome de host e ver se o host está ativo, use
ping
!Será
ping
o host uma vez e resolver o nome do host para o endereço IP.fonte
Sim, já existem muitas respostas, mas falta uma solução usando perl:
Em um script bash, poderia ser usado assim:
Os módulos usados aqui são módulos principais, portanto devem estar disponíveis em qualquer lugar sem a instalação com o CPAN.
fonte
perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null
é muito mais limpo. mas ninguém, exceto nós dois, estamos usando pörl, todos os outros usam o Pascal Script, é claro.Can't call method "addr" on an undefined value
não é exatamente a melhor mensagem de erro, mas pode dar uma dica sobre o problema.fonte
print
deve ser usado em vez dep
.este comando mostrará o endereço IP (reslove o domínio para o IP)
fonte
Além da solução acima, você pode traduzir vários nomes de host para ip via script abaixo, a única dependência é o comando "ping" no núcleo Unix:
fonte