Extraia seu IP externo usando ferramentas de linha de comando

Para dizer a conclusão primeiro,
(e obrigado@alfredormz para isso!)
a forma mais elegante e rápida é esta:

dig +short myip.opendns.com @resolver1.opendns.com

Isso pede o endereço IP do myip.opendns.comservidor de nomes resolver1.opendns.com(algo em que você confia),
que retornará seu endereço IP externo.

Se não tiver dig,
você pode usar estas alternativas:

curl ipecho.net/plain
curl icanhazip
.com
curl curlmyip
.com
curl l2
.io/ip
curl ip
.appspot.com
curl ifconfig
.me/ip
curl eth0
.me

Ou se você precisar no formato JSON:

curl httpbin.org/ip
curl wtfismyip
.com/json

Eles funcionam em HTTP
e , portanto, menos eficientes do que a consulta DNS direta com dig.

Ao usar qualquer uma dessas soluções,
lembre-se de que você está contando com serviços externos.
Eles podem estar indisponíveis temporariamente ou mesmo permanentemente em algum ponto.
Portanto, nenhum desses é perfeito.

Este artigo é, na verdade, sobre outra coisa.
É sobre o desafio de extrair as partes relevantes de um texto curto.
Recentemente, precisei extrair meu endereço IP externo de http://monip.org/ usando ferramentas de linha de comando.
Este artigo é sobre como explicar o processo de pensamento,
caso você precise de algo semelhante.

Vamos ver o que conseguimos com um simples curl:

$ curl monip.org
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>MonIP.org v1.0</title>
<META http-equiv="Content-type" content="text/html; charset=ISO-8859-1">
</head>
<P ALIGN="center"><FONT size=8><BR>IP : 67.205.36.164<br></font><font size=3><i>genovese.dreamhost.com</i><br></font><font size=1><br><br>Pas de proxy d�tect� - No Proxy detected</font></html>

Uma maneira de extrair o endereço IP disso é usando sed:

$ curl -s monip.org | sed -n 's/.*IP : ([0-9.]*).*/1/p'
67.205.36.164tect - No Proxy detected</font></html>

Ugh. Quase funciona, mas quase:
sobra um pouco de lixo no final.
Eu realmente não sei por que o .*no final não apagou tudo após o endereço IP.
Parece que sedtem problemas com alguns personagens não ASCII.
Olhando para a saída original,
parece que o site usa a codificação ISO-8859-1,
então , se colocarmos um iconvno pipeline, ele pode corrigir o problema:

$ curl -s monip.org | iconv -f iso-8859-1 | sed -n 's/.*IP : ([0-9.]*).*/1/p'
67.205.36.164

Muito melhor! Vamos ver como isso sedfunciona:

  • Por padrão, sedecoa as linhas que processa.
    O sinalizador desliga isso: ele apenas imprimirá qualquer coisa com comandos de impressão explícitos.-n

  • Uma técnica para extrair um padrão de algum corpo de texto está utilizando a expressão: . O na substituição é uma referência anterior ao padrão que foi correspondido na primeira expressão. O antes e o depois do padrão de interesse devem fazer com que o padrão de pesquisa corresponda a toda a linha, de modo que o resultado da substituição seja a linha inteira substituída pelo padrão de interesse.s/.*(pattern).*/1/
    1(...)
    .*

  • Usamos como padrão. Esta é uma abordagem imprecisa, preguiçoso, e nós poderia ter sido muito mais precisa, por exemplo: . Depende de você e da tarefa dada onde você traça a linha..*IP : ([0-9.]*).*


    .*IP : ([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})>.*

  • A pbandeira no idioma faz imprimir a linha apenas se houver uma substituição. Isso é perfeito para o nosso propósito: desta forma só será impressa a linha com o endereço IP, após a substituição, então a saída será simplesmente o próprio endereço IP.s///psed



A propósito,
quando eu fiz isso pela primeira vez, o problema de codificação com sedminha primeira reação foi usar perl:

curl -s monip.org | perl -ne '/IP : ([0-9.]+)/ && print $1'

Ele usa a lógica de extração equivalente como no anterior sed,
com algumas diferenças devido à natureza dessas ferramentas:

  • O sinalizador é para executar uma expressão Perl fornecida na linha de comando, em oposição a um arquivo especificado.-e

  • O sinalizador envolve a expressão dentro de um bloco, tornando-o adequado para o processamento de entrada padrão linha por linha.-nwhile (<>) { ... }

  • A correspondência de padrões é um pouco mais simples em comparação com sed,
    porque sedusa expressões regulares básicas (BRE),
    e Perl usa PCRE, que é muito mais avançado.

  • Em Perl, você pode usar para trás referências a padrões capturados dentro de (...)expressões usando as variáveis $1, $2e assim por diante.

  • O idioma significa, se o padrão foi correspondido, imprimir o conteúdo do primeiro grupo./(pattern)/ && print $1