¿Cómo puedo obtener mi propia dirección IP y guardarla en una variable en un script de shell?
networking
shell-script
ip
Tom Brito
fuente
fuente
Respuestas:
No es tan fácil si desea tener en cuenta wlan y otras interfaces alternativas. Si sabe para qué interfaz desea la dirección (por ejemplo, eth0, la primera tarjeta Ethernet), puede usar esto:
En otras palabras, consígueme la información de configuración de la red, busque
eth0
, obtenga esa línea y la siguiente (-A 1
), obtenga solo la última línea, obtenga la segunda parte de esa línea al dividir con:
, luego obtenga la primera parte de eso al dividir con espaciofuente
grep
a su código para ignorar cualquier interfaz con "eth0:" en él; esto ahora funciona como esperaba (dando solo la dirección IP "eth0" y no ninguna subinterfaz (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
en su lugarCreo que la forma de "herramientas modernas" para obtener su dirección ipv4 es analizar 'ip' en lugar de 'ifconfig', por lo que sería algo así como:
o algo así.
fuente
ip
está disponible en todas las distribuciones de Red Hat y Fedora que he usado.ip
es parte del paquete iproute2 ( linuxfoundation.org/collaborate/workgroups/networking/iproute2 ).ifconfig
yroute
supuestamente están en desuso, aunque muchas personas continúan usándolas, especialmente en los guiones.ip
es mucho más fácil de analizar, en mi opinión.ip
también está disponible en todas las distribuciones basadas en Debian y Debian que he visto. Es parte del paquete iproute que está marcado como importante.ip
es parte del paquete iproute2, que es una distribución por defecto. Está en la mayoría de los buenos repositorios. en.wikipedia.org/wiki/Iproute2/sbin/ip
lugar deip
?awk
ycut
es levemente divertida para mí, aquí hay una posible alternativa que en realidad puede no ser mejor:ip -o -4 addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'
¿Por qué no simplemente hacer
IP=$(hostname -I)
?fuente
hostname -i
me da solo127.0.0.1
,hostname -I
me da la dirección IP correcta ...-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
, junto con la dirección IP correspondiente-I
en FreeBSD, pero puedes usarlodig +short `hostname -f`
Si desea la dirección de una interfaz, la forma más fácil es instalar moreutils y luego:
ifdata
responde casi todas las preguntas por las que te sentirías tentado a analizar laifconfig
salida.Si desea averiguar su dirección IP como la ve el exterior (más allá de cualquier NAT, etc.), hay muchos servicios que lo harán. Uno es bastante fácil:
fuente
ifdata
agregadoiproute2
. Tal vez un nuevo binario llamadoipdata
Para obtener direcciones IPv4 e IPv6, y no asumir que la interfaz principal es
eth0
(en estos díasem1
es más común ), intente:-o
utiliza el formato de salida de una línea, que es más fácil de procesar conread
,grep
, etc.up
excluye dispositivos que no están activosscope global
excluye direcciones privadas / locales como127.0.0.1
yfe80::/64
primary
excluye direcciones temporales (suponiendo que desea una dirección que no cambie)fuente
-4
/-6
filtrar tipos de direcciones. También puede obtener fácilmente otros parámetros de la interfaz. Personalmente, no me gusta el bucle while y prefierogrep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
Depende de lo que quiera decir con su propia dirección IP. Los sistemas tienen direcciones IP en varias subredes (a veces varias por subred), algunas de las cuales son IPv4, algunas IPv6 que utilizan dispositivos como adaptadores de Ethernet, interfaces de bucle invertido, túneles VPN, puentes, interfaces virtuales ...
Me refiero a la dirección IP por la cual otro dispositivo puede llegar a su computadora, debe averiguar qué subred es esa y qué versión de IP estamos hablando. Además, tenga en cuenta que debido a NAT realizada por firewall / enrutadores, la dirección IP de una interfaz puede no ser la misma que un host remoto ve una conexión entrante desde su computadora.
Cuando hay un enrutamiento de origen elegante o por enrutamiento de protocolo / puerto, puede ser difícil averiguar qué interfaz se usaría para hablar con una computadora remota a través de un protocolo dado e incluso entonces, no hay garantía de que la dirección IP de esa interfaz pueda ser directamente direccionable por la computadora remota que desea establecer una nueva conexión a su computadora.
Para IPv4 (probablemente también funciona para IPv6), un truco que funciona en muchos dispositivos, incluido Linux, para averiguar la dirección IP de la interfaz utilizada para llegar a un host determinado es usar una conexión (2) en un socket UDP y usar getsockname ():
Por ejemplo, en la computadora de mi casa:
Se utilizaría para averiguar la dirección IP de la interfaz a través de la cual llegaría a 8.8.8.8 (el servidor DNS de Google). Devolvería algo como "192.168.1.123", que es la dirección de la interfaz para la ruta predeterminada a Internet. Sin embargo, Google no vería que una solicitud de DNS de mi máquina provenga de esa dirección IP, que es privada, ya que el enrutador de banda ancha de mi casa realiza NAT.
connect () en un socket UDP no envía ningún paquete (UDP no tiene conexión), pero prepara el socket consultando la tabla de enrutamiento.
fuente
fuente
-I
lugar de-i
es mejor, ya que desearía ignorar las direcciones de bucle invertido, por lo que el comando final seríaipa=$(hostname -I|cut -f1 -d ' ')
grep
no es suficiente, no lo canalices a otra cosa. Sólo tiene que utilizar la otra cosa (sed
,awk
, etc.).No quiero ser un imbécil, pero realmente hay una manera correcta y esta es. Recorta la salida de
ip route
para obtener solo la IP de origen. Dependiendo de qué IP está tratando de alcanzar, "mi propia dirección IP" (palabras de OP) será diferente. Si te interesa llegar a Internet público, usar el servidor DNS 8.8.8.8 de Google es bastante estándar. Entonces...La respuesta corta es:
Aquí está la explicación detallada.
Si quiero que la ip que uso llegue a internet , uso esto:
Si quiero que la ip que utilizo llegue a algo en mi VPN , uso esto:
Si quisiera que la ip que utilizo me alcance , usaría esto:
Más sobre ese
sed
comandoPrimero permítanme decir que al elegir las herramientas de Unix, intentan elegir las herramientas que requieren la menor cantidad de tuberías. Así, mientras que algunas respuestas serán tubería
ifconfig
agrep
ased
ahead
, que es rara vez es necesario. Cuando lo vea, debería mostrar una señal de alerta de que está recibiendo consejos de alguien con poca experiencia. Eso no hace que la "solución" sea incorrecta. Pero, probablemente podría usar alguna racionalización.Elegí
sed
porque es más breve que el mismo flujo de trabajoawk
. (Lo he hecho desde un ejemplo awk a continuación.) No creo que haya ninguna otra herramienta, pero esas 2 serían apropiadas.Examinemos qué
Nota:sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
hace:Solía usar,
sed -n '/src/{s/.*src *//p;q}'
pero un comentarista señaló que algunos sistemas tienen datos finales después delsrc
campo.Usando awk
Más acerca de mi red
Mis
ifconfig
shows que tengotun0
para mi VPN yeth0
para mi lan.fuente
ip route get 8.8.8.8 | sed -n '/src/{s/.*src *//p;q}'
me dio10.1.2.3 uid 1002
. Entonces agrego agregar| awk '{print $1}'
para mantener solo la dirección IP.En FreeBSD puedes usar
Esto puede funcionar para otros entornos, depende de su configuración.
fuente
/etc/resolv.conf
y de cómo el enrutador de red maneja los nombres de host locales. Está bien usar esto en su entorno si lo prueba y funciona. Pero si lo hace, está creando un sistema "frágil" que causará otros problemas si comparte esto. Usar con precaución.Suponiendo que puede tener varias interfaces de varios nombres pero que desea la primera no localhost y no ipv6, puede intentar:
fuente
Yo uso este one-liner:
Usos
ifconfig
(ampliamente disponible), no tomalocalhost
dirección, no lo vincula a un nombre de interfaz dado, no tiene en cuenta IPv6 e intenta obtener la IP de la primera interfaz de red disponible.fuente
o
fuente
Debería usar
ip
(en lugar deifconfig
) ya que es actual, se mantiene y, quizás lo más importante, para fines de secuencias de comandos, produce una salida coherente y analizable. Los siguientes son algunos enfoques similares:Si desea la dirección IPv4 para su interfaz Ethernet
eth0
:Como un guión:
La salida producida anteriormente está en notación CIDR. Si no se desea la notación CIDR, se puede quitar:
Otra opción que en mi humilde opinión es "más elegante" obtiene la dirección IPv4 para cualquier interfaz que se utilice para conectarse al host remoto especificado (8.8.8.8 en este caso). Cortesía de @gatoatigrado en esta respuesta :
Como un guión:
Esto funciona perfectamente bien en un host con una sola interfaz, pero más ventajosamente también funcionará en hosts con múltiples interfaces y / o especificaciones de ruta.
ip
sería mi enfoque preferido, pero ciertamente no es la única forma de desollar a este gato. Aquí hay otro enfoque que utilizahostname
si prefiere algo más fácil / más conciso:O, si desea la dirección IPv6:
fuente
Necesitaba hacer esto dentro de un alias para iniciar un servidor de radio en mi NIC cableada. solía
fuente
egrep
es depreciado Usar en sugrep -E
lugar.Algunos comandos funcionan en centos 6 o 7, el siguiente comando funciona en ambos,
fuente
grep | awk | awk
. la línea se puede acortar a/sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } '
Suponiendo que necesita su IP pública primaria como se ve desde el resto del mundo , pruebe cualquiera de los siguientes:
fuente
Este fragmento evita codificar el nombre del dispositivo (como 'eth0') y usará en
ip
lugar deifconfig
:Devolverá la IP del primer dispositivo activo listado en la salida de
ip addr
. Dependiendo de su máquina, esta puede ser una dirección ipv4 o ipv6.Para almacenarlo en una variable, use:
fuente
todas las soluciones que usan awk / sed / grep parecen demasiado complejas y feas para mi situación ... así que se me ocurrió esta solución realmente simple PERO cuidado porque hace algunas suposiciones, a saber, la suposición de que la ÚLTIMA interfaz es la que estás interesado. si estás de acuerdo con eso, entonces esto está bastante limpio:
ifconfig | awk '/net / { x = $2 } END { print x }'
de lo contrario, podría hacer una
if
declaración tonta para probar un prefijo específico o cualquier criterio que pueda tener.fuente
Comando simple para ajustar la dirección IP con la interfaz predeterminada.
Probado en todos los sistemas operativos Unix
fuente
Puede que esta no sea la solución más sólida o correcta, pero a diferencia de la mayoría de las otras soluciones, el comando funciona tanto en Linux como en Mac (BSD).
fuente
Si está buscando una dirección IP pública del cuadro , puede usar lo siguiente:
dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"
Puede usar
dig(1)
opciones como-4
o-6
para buscar específicamente una dirección IPv4 o IPv6; Google proporcionará una respuesta en un registro deTXT
tipo, que tendrá citas a su alrededor cuando sea presentado pordig
; si desea usar posteriormente la variable con utilidades comotraceroute
, debe usar algo como tr (1) para eliminar dichas comillas.Otras opciones incluyen
whoami.akamai.net
ymyip.opendns.com
, que responden conA
yAAAA
registros (en lugar deTXT
como en el ejemplo anterior de Google), por lo que no requieren que se eliminen las comillas: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
Aquí hay un script de muestra que usa todas las opciones anteriores para establecer las variables:
Si está buscando una dirección IP privada, o un conjunto de todas las direcciones IP asignadas a la caja, puede usar alguna combinación de
ifconfig
(en BSD y GNU / Linux),ip addr
(en GNU / Linux),hostname
(opciones-i
y-I
en GNU / Linux) ynetstat
para ver qué está pasando.fuente
esto hará todo lo que quieras
fuente
hostname: invalid option -- 'l'
...