Como posso obter meu próprio endereço IP e salvá-lo em uma variável em um script de shell?
networking
shell-script
ip
Tom Brito
fonte
fonte
Respostas:
Não é tão fácil se você quiser levar em consideração a wlan e outras interfaces alternativas. Se você souber para qual interface deseja o endereço (por exemplo, eth0, a primeira placa Ethernet), poderá usar este:
Em outras palavras, obtenha as informações de configuração de rede, procure
eth0
, obtenha essa linha e a próxima (-A 1
), obtenha apenas a última linha, obtenha a segunda parte dessa linha ao dividir e:
, em seguida, obtenha a primeira parte disso ao dividir com espaço.fonte
grep
ao seu código para ignorar qualquer interface com "eth0:"; isso agora funciona como eu esperava (fornecendo apenas o endereço IP "eth0" e não quaisquer subinterfaces (eth0: 0, eth0: 1 etc.):ip="$(ifconfig | grep -v 'eth0:' | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
ifconfig eth0
ip address
vez dissoEu acredito que a maneira "ferramentas modernas" de obter seu endereço ipv4 é analisar 'ip' em vez de 'ifconfig', então seria algo como:
ou algo assim.
fonte
ip
está disponível em todas as distribuições Red Hat e Fedora que eu usei.ip
faz parte do pacote iproute2 ( linuxfoundation.org/collaborate/workgroups/networking/iproute2 ).ifconfig
eroute
são supostamente preteridos, embora continuem sendo usados por muitas pessoas, principalmente em scripts.ip
é muito mais analisável, na minha opinião.ip
também está disponível em todas as distribuições baseadas em Debian e Debian que eu já vi. Faz parte do pacote iproute que é marcado como importante.ip
faz parte do pacote iproute2, que é muitas distribuições por padrão. É na maioria dos bons repositórios de. pt.wikipedia.org/wiki/Iproute2/sbin/ip
vez deip
?awk
ecut
é levemente divertida para mim, aqui está uma alternativa possível que pode não ser realmente melhor: #ip -o -4 addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'
Por que não simplesmente fazer
IP=$(hostname -I)
?fonte
hostname -i
dá-me apenas127.0.0.1
,hostname -I
dá-me o endereço IP correto ...-i Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses
/etc/hosts
, juntamente com o endereço IP correspondente-I
no FreeBSD, mas você pode usardig +short `hostname -f`
Se você deseja o endereço de uma interface, a maneira mais fácil é instalar o moreutils:
ifdata
responde praticamente todas as perguntasifconfig
pelas quais você seria tentado a analisar a saída.Se você deseja descobrir o seu endereço IP como o exterior o vê (além de qualquer NAT, etc.), existem muitos serviços que o farão. Um é bastante fácil:
fonte
ifdata
adicionadoiproute2
. Talvez um novo binário chamadoipdata
Para obter endereços IPv4 e IPv6 e não assumir que a interface principal seja
eth0
(atualmenteem1
é mais comum ), tente:-o
utiliza o formato de saída de uma linha, que é mais fácil de processar comread
,grep
, etc.up
exclui dispositivos que não estão ativosscope global
exclui endereços particulares / locais como127.0.0.1
efe80::/64
primary
exclui endereços temporários (supondo que você queira um endereço que não seja alterado)fonte
-4
/-6
para filtrar os tipos de endereço. Você também pode obter facilmente outros parâmetros de interface. Pessoalmente, eu não gosto while e eu prefirogrep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
Depende do que você quer dizer com seu próprio endereço IP. Os sistemas têm endereços IP em várias sub-redes (algumas vezes por sub-rede), algumas das quais IPv4, outras IPv6 usando dispositivos como adaptadores Ethernet, interfaces de loopback, túneis VPN, pontes, interfaces virtuais ...
Você quer dizer o endereço IP pelo qual outro dispositivo pode chegar ao seu computador, você precisa descobrir qual sub-rede é essa e qual versão do IP estamos falando. Além disso, lembre-se de que, devido ao NAT executado pelos firewalls / roteadores, o endereço IP de uma interface pode não ser o mesmo que um host remoto vê uma conexão de entrada do seu computador.
Quando há um roteamento de origem sofisticado ou por protocolo / porta, pode ser difícil descobrir qual interface seria usada para conversar com um computador remoto por um determinado protocolo e, mesmo assim, não há garantia de que o endereço IP dessa interface seja diretamente endereçável pelo computador remoto que deseja estabelecer uma nova conexão com o seu computador.
Para o IPv4 (provavelmente também funciona para o IPv6), um truque que funciona em muitos departamentos, incluindo o Linux, para descobrir o endereço IP da interface usada para alcançar um determinado host, é usar um connect (2) em um soquete UDP e usar o nome do obturador ():
Por exemplo, no meu computador doméstico:
Seria usado para descobrir o endereço IP da interface através do qual eu alcançaria 8.8.8.8 (servidor DNS do Google). Ele retornaria algo como "192.168.1.123", que é o endereço da interface para a rota padrão para a Internet. No entanto, o Google não vê uma solicitação DNS da minha máquina como proveniente desse endereço IP, que é privado, pois há NAT realizado pelo meu roteador de banda larga doméstico.
connect () em um soquete UDP não envia nenhum pacote (UDP é sem conexão), mas prepara o soquete consultando a tabela de roteamento.
fonte
fonte
-I
vez de-i
é melhor que você iria querer ignorar endereços de loopback, então o comando final seriaipa=$(hostname -I|cut -f1 -d ' ')
grep
não for suficiente, não o coloque em outra coisa. Basta usar a outra coisa (sed
,awk
, etc.).Não pretendo ser um idiota, mas realmente existe um caminho certo e é isso. Você apara a saída
ip route
para obter apenas o IP de origem. Dependendo do IP que você está tentando acessar, "meu próprio endereço IP" (palavras do OP) será diferente. Se você se preocupa em acessar a Internet pública, usar o servidor DNS 8.8.8.8 do Google é bastante padrão. Assim...A resposta curta é:
Aqui está a explicação detalhada
Se eu quero o ip que eu uso para acessar a internet , eu uso o seguinte:
Se eu quiser que o ip que eu uso alcance algo na minha VPN , eu uso o seguinte:
Se eu quisesse que o ip que eu utilizasse chegasse a mim , eu usaria o seguinte:
Mais sobre esse
sed
comandoPrimeiro, deixe-me dizer que, ao escolher as ferramentas unix, você tenta escolher as ferramentas que requerem menos tubos. Portanto, embora algumas respostas sejam direcionadas
ifconfig
degrep
parased
parahead
, isso raramente é necessário. Quando você o vir, deve ser sinalizado que você está seguindo conselhos de alguém com pouca experiência. Isso não faz a "solução" errada. Mas, provavelmente, poderia usar alguma racionalização.Eu escolhi
sed
porque é mais conciso do que o mesmo fluxo de trabalhoawk
. (Eu tenho desde um exemplo estranho abaixo.) Eu não acho que nenhuma outra ferramenta, mas essas 2 seriam apropriadas.Vamos examinar o que
Nota:sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
faz:Eu costumava usar,
sed -n '/src/{s/.*src *//p;q}'
mas um comentarista apontou que alguns sistemas têm dados finais após osrc
campo.Usando awk
Mais sobre minha rede
Meus
ifconfig
programas que tenhotun0
para minha VPN eeth0
para minha LAN.fonte
ip route get 8.8.8.8 | sed -n '/src/{s/.*src *//p;q}'
me deu10.1.2.3 uid 1002
. Então eu adiciono ao anexo| awk '{print $1}'
para manter apenas o endereço IP.No FreeBSD você pode usar
Isso pode funcionar para outros ambientes, depende da sua configuração.
fonte
/etc/resolv.conf
e de como o roteador de rede lida com nomes de host locais. É bom usar isso em seu ambiente se você testá-lo e funcionar. Mas se você fizer isso, estará criando um sistema "quebradiço" que causará problemas a outros se você compartilhar isso. Use com cuidado.Supondo que você possa ter várias interfaces de vários nomes, mas que deseje o primeiro host não local e o não ipv6, tente:
fonte
Eu uso este one-liner:
Usa
ifconfig
(amplamente disponível), não levalocalhost
endereço, não o vincula a um determinado nome de interface, não leva em consideração o IPv6 e tenta obter o IP da primeira interface de rede disponível.fonte
ou
fonte
Você deve usar
ip
(em vez deifconfig
) como é atual, mantida e talvez o mais importante para fins de script, produz uma saída consistente e analisável. A seguir, algumas abordagens semelhantes:Se você deseja o endereço IPv4 para sua interface Ethernet
eth0
:Como um script:
A saída produzida acima está na notação CIDR. Se a notação CIDR não for desejada, ela poderá ser removida:
Outra opção que o IMHO é "mais elegante" obtém o endereço IPv4 para qualquer interface usada para conectar-se ao host remoto especificado (8.8.8.8 neste caso). Cortesia de @gatoatigrado em esta resposta :
Como um script:
Isso funciona perfeitamente bem em um host com uma única interface, mas mais vantajosamente também funcionará em hosts com várias interfaces e / ou especificações de rota.
ip
seria minha abordagem preferida, mas certamente não é a única maneira de esfolar esse gato. Aqui está outra abordagem usadahostname
se você preferir algo mais fácil / mais conciso:Ou, se você deseja o endereço IPv6:
fonte
Eu precisava fazer isso dentro de um alias para iniciar um servidor de rádio na minha NIC com fio. eu usei
fonte
egrep
é depreciado. Use emgrep -E
vez disso.Alguns comandos estão trabalhando nos centos 6 ou 7, o comando abaixo trabalhando nos dois,
fonte
grep | awk | awk
. linha pode ser encurtada para/sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } '
Supondo que você precise do seu IP público primário , visto do resto do mundo , tente um destes:
fonte
Este trecho evita codificar o nome do dispositivo (como 'eth0') e usará em
ip
vez deifconfig
:Ele retornará o IP do primeiro dispositivo ativo listado na saída de
ip addr
. Dependendo da sua máquina, este pode ser um endereço ipv4 ou ipv6.Para armazená-lo em uma variável, use:
fonte
todas as soluções que usam awk / sed / grep parecem muito complexas e feias para a minha situação ... então, eu vim com essa solução realmente simples, mas cuidado, pois ela faz algumas suposições, a saber, a suposição de que a ÚLTIMA interface é a que você está interessado. se você estiver bem com isso, isso é bastante limpo:
ifconfig | awk '/net / { x = $2 } END { print x }'
caso contrário, você poderá fazer uma
if
declaração boba para testar um prefixo específico ou qualquer critério que possa ter.fonte
Comando simples para refinar o endereço IP com interface padrão.
Testado em todos os sistemas operacionais Unix
fonte
Essa pode não ser a solução mais robusta ou correta, mas, diferentemente da maioria das outras soluções, o comando funciona no Linux e no Mac (BSD).
fonte
Se você estiver procurando por um endereço IP público da caixa , use o seguinte:
dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"
Você pode usar
dig(1)
opções como-4
ou-6
procurar especificamente um endereço IPv4 ou IPv6; O Google fornecerá uma resposta em um registro doTXT
tipo, que terá aspas quando apresentado pordig
; se você quiser usar a variável posteriormente com utilitários comotraceroute
, precisará usar algo como tr (1) para remover as citações.Outras opções incluem
whoami.akamai.net
emyip.opendns.com
, que respondem comA
eAAAA
registros (em vez deTXT
no exemplo acima do Google), portanto, não exigem a remoção das aspas:dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short
dig -4 @resolver1.opendns.com -t any myip.opendns.com +short
dig -6 @resolver1.opendns.com -t any myip.opendns.com +short
Aqui está um exemplo de script que usa todas as opções acima para definir as variáveis:
Se você estiver procurando por um endereço IP privado ou por um conjunto de todos os endereços IP atribuídos à caixa, poderá usar uma combinação de
ifconfig
(no BSD e GNU / Linux),ip addr
(no GNU / Linux),hostname
(opções-i
e-I
em GNU / Linux) enetstat
para ver o que está acontecendo.fonte
isso fará tudo o que você quiser
fonte
hostname: invalid option -- 'l'
...