Puxando endereço IP do comando ping com sed? [duplicado]

2

Eu criei uma ferramenta Bash que é executada em um servidor. Esta ferramenta irá bloquear determinados endereços IP para um determinado intervalo de tempo (por exemplo, das 5:00 às 15:30).

Atualmente, a ferramenta funciona bem, mas eu tenho que inserir endereços IP em determinados sites manualmente em um arquivo de texto e ter a ferramenta puxar o endereço IP com base na enésima linha usando os comandos "head" e "tail" . Eu não quero fazer isso, pois acredito que um único ping será muito mais leve e portátil. Então, se eu fizer um ping para o Google:

ping google.com -c 1 -s 16

A saída será:

Ubuntu@yokai:~# ping google.com -c 1 -s 16
PING google.com (173.194.66.138) 16(44) bytes of data.
24 bytes from qo-in-f138.1e100.net (173.194.66.138): icmp_seq=1 ttl=37 time=46.7 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 46.748/46.748/46.748/0.000 ms

E o comando que eu reduzi esta saída é:

ping google.com -c 1 -s 16 | grep -o '([^ ]*' | tr -d '(44):\n'

O que me dá uma saída de:

173.19.66.113173.19.66.113ubuntu@yokai

Como você pode ver, há uma duplicata do mesmo endereço IP. Como posso remover a duplicata com sed para que eu possa armazenar o endereço IP único em uma variável e executar o script como um cronjob ou estou em uma faixa melhor usando tr?

(EDITAR)

Eu já sei / sabia como resolver o endereço IP de um nome de host ou domínio. Não é isso que estou perguntando aqui. Esta questão é especificamente sobre o gerenciamento de saída de ping usando sed, a fim de manter a ferramenta que eu criei mais portátil como ping vem por padrão com quase todas as distros linux.

(ATUALIZAÇÃO) Já que alguns deles marcaram essa questão como uma duplicata de alguma outra pergunta besteira que não tem nada a ver com essa, eu deixarei claro o suficiente que retardas com problemas de compreensão em inglês podem entender:

Como analisar o ENDEREÇO IP "SOMENTE" de ping OUTPUT ao usar ping em um nome de domínio.

Isso NÃO está pedindo para resolver um nome de domínio e, portanto, NÃO É DUPLICADO !!!

(ATUALIZAÇÃO MAIS RECENTE) Eu tenho, desde que fiz esta pergunta, aprendi regex POSIX adequado para fazer o que eu precisava e preciso deixar claro que eu estava originalmente perguntando sobre as expressões regulares para sed que iria imprimir uma única instância de um IP de saída de ping. Eu já refinei meus métodos e não usei nenhuma das respostas aqui, mas agradeço a todos por suas tentativas de ajudar aqui. Agora estou usando um script de timer que criei para configurar o iptables em determinados momentos para bloquear determinadas resoluções de nomes de domínio. Mais uma vez, obrigado a todos que tentaram ajudar.

    
por Yokai 05.09.2016 / 04:44

3 respostas

8

ping é para verificar se um host está ativo ou inativo com base na resposta do ICMP, nunca é a ferramenta certa para resolver apenas o endereço IP, existem ferramentas dedicadas para isso.

Você deve analisar dig , host , nslookup - o que for melhor para você.

Aqui está uma dig output:

% dig +short google.com
123.108.243.57
123.108.243.51
123.108.243.54
123.108.243.48
123.108.243.60
123.108.243.52
123.108.243.56
123.108.243.55
123.108.243.61
123.108.243.58
123.108.243.49
123.108.243.50
123.108.243.59
123.108.243.47
123.108.243.53

Como observação, no Linux, se você quiser consultar pelo NSSwitch (Name Service Switch), isto é, /etc/nsswitch , use o comando getent com o banco de dados hosts (ou ahosts ), por exemplo:

getent hosts google.com

No meu computador, eu tenho:

hosts: files mdns4 dns

em /etc/nsswitch.conf , então getent hosts consultará em sequência e usar gethostbyaddr(3) ou gethostbyname(3) com base no nome e ahosts usará getaddrinfo(3) .

Em essência, com minha configuração, isso primeiro verificará /etc/hosts , depois mDNS e, finalmente, DNS.

Se você insistir em usar ping e sed , poderá fazer:

% ping -c1 google.com | sed -nE 's/^PING[^(]+\(([^)]+)\).*//p'
123.108.243.56
    
por 05.09.2016 / 05:09
2

Navegando no Google, encontrei um link para outro unix.SE que menciona getent - eu nem sabia que esse programa existia.

Você pode usar getent como dig para resolver um IP para um nome de host - e meu sistema tinha getent instalado por padrão, mas não dig . Se você quiser hosts ipv6, altere ahostsv4 para ahostsv6 .

getent ahostsv4 google.com | awk '{print $1}' | head -1

Eu adicionei essa resposta porque sou ruim em regexes / sed e não teria sido capaz de encontrar a resposta do @ heemayl.

    
por 05.09.2016 / 07:38
2

Uma coisa a notar é que, como você vê na saída dig do @heyemayl, alguns sites podem ter mais de um endereço IP. Você provavelmente precisará de uma pesquisa de DNS para obtê-los todos, pois ping apenas usará o primeiro endereço obtido. O mesmo vale para qualquer outra coisa que queira se conectar e não listar especificamente os endereços.

(Além disso, no caso de algo como o google, você terá endereços IP diferentes, dependendo de onde você estiver. Não será um problema aqui, mas é bom notar.)

Outra coisa, sobre o comando que você usou. Isso: tr -d '(44):\n' remove todas as cópias dos caracteres ( , 4 , ) , : e \n da entrada. tr sempre olha apenas caracteres únicos, não seqüências de caracteres. Olhando para a saída que você obteve, você verá que um 4 desapareceu do meio do endereço IP. Use alguma outra ferramenta como sed para trabalhar com strings.

Apenas para mostrar cores diferentes para o bike shed , aqui está outro simples, com o GNU grep:

$ ping google.com -c1 | head -1 | grep -Eo '[0-9.]{4,}'
172.217.22.174
    
por 05.09.2016 / 09:41