Estoy en el proceso de mantener una aplicación Ruby on Rails y estoy buscando una manera fácil de encontrar el nombre de host o la dirección IP de la caja en la que estoy (ya que es una máquina virtual y las nuevas instancias pueden tener diferentes nombres de host o direcciones IP) . ¿Existe una forma rápida y sencilla de hacer esto en Ruby on Rails?
Editar: la respuesta a continuación es correcta, pero la aclaración que proporcionó Craig es útil (consulte también el enlace proporcionado en la respuesta):
El código [a continuación] NO establece una conexión ni envía ningún paquete (al 64.233.187.99 que es Google). Dado que UDP es un protocolo sin estado, connect () simplemente realiza una llamada al sistema que descubre cómo enrutar los paquetes en función de la dirección y a qué interfaz (y por lo tanto la dirección IP) debe unirse. addr () devuelve una matriz que contiene la familia (AF_INET), el puerto local y la dirección local (que es lo que queremos) del socket.
fuente
Nombre de host
Una forma sencilla de obtener el nombre de host en Ruby es:
require 'socket' hostname = Socket.gethostname
El problema es que esto depende de que el host conozca su propio nombre porque usa la llamada al sistema
gethostname
ouname
, por lo que no funcionará para el problema original.Funcionalmente, esto es idéntico a la
hostname
respuesta, sin invocar un programa externo. El nombre de host puede estar completamente calificado o no, según la configuración de la máquina.Dirección IP
Desde ruby 1.9, también puede usar la biblioteca Socket para obtener una lista de direcciones locales.
ip_address_list
devuelve una matriz de objetos AddrInfo . La forma en que elija dependerá de lo que quiera hacer y de cuántas interfaces tenga, pero aquí hay un ejemplo que simplemente selecciona la primera dirección IP IPV4 sin bucle invertido como una cadena:require 'socket' ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
fuente
Prueba esto:
host = `hostname`.strip # Get the hostname from the shell and removing trailing \n puts host # Output the hostname
fuente
hostname
se va a trabajar, no se puede superar, por simplicidaduname -n
.sub (/\..*/, '')Un servidor suele tener más de una interfaz, al menos una privada y una pública.
Dado que todas las respuestas aquí tratan con este escenario simple, una forma más limpia es pedirle a Socket la corriente
ip_address_list()
como en:require 'socket' def my_first_private_ipv4 Socket.ip_address_list.detect{|intf| intf.ipv4_private?} end def my_first_public_ipv4 Socket.ip_address_list.detect{|intf| intf.ipv4? and !intf.ipv4_loopback? and !intf.ipv4_multicast? and !intf.ipv4_private?} end
Ambos devuelven un objeto Addrinfo, por lo que si necesita una cadena, puede usar el
ip_address()
método, como en:ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?
Puede encontrar fácilmente la solución más adecuada para su caso cambiando los métodos de Addrinfo utilizados para filtrar la dirección de interfaz requerida.
fuente
Esta dirección IP utilizada aquí es de Google, pero puede usar cualquier IP accesible.
require "socket" local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
fuente
El más simple está
host_with_port
en controller.rbfuente
La respuesta aceptada funciona, pero debe crear un conector para cada solicitud y no funciona si el servidor está en una red local y / o no está conectado a Internet. Lo siguiente, creo que siempre funcionará ya que está analizando el encabezado de la solicitud.
request.env["SERVER_ADDR"]
fuente
Ponga la parte resaltada con comillas invertidas:
`dig #{request.host} +short`.strip # dig gives a newline at the end
O simplemente
request.host
si no te importa si es una IP o no.fuente
Similar a la respuesta usando
hostname
, usando eluname
comando externo en UNIX / LINUX:hostname = `uname -n`.chomp.sub(/\..*/,'') # stripping off "\n" and the network name if present
para las direcciones IP en uso (su máquina podría tener múltiples interfaces de red), podría usar algo como esto:
# on a Mac: ip_addresses = `ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d' ' -f 2`.split => ['10.2.21.122','10.8.122.12'] # on Linux: ip_addresses = `ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d':' -f 2 | cut -d' ' -f 1`.split => ['10.2.21.122','10.8.122.12']
fuente
Es probable que tenga varias direcciones IP en cada máquina (127.0.0.1, 192.168.0.1, etc.). Si está usando * NIX como su sistema operativo, le sugiero que lo use
hostname
y luego ejecute una búsqueda de DNS en eso. Debería poder usar / etc / hosts para definir el nombre de host local para resolverlo en la dirección IP de esa máquina. Hay una funcionalidad similar en Windows, pero no la he usado desde que Windows 95 fue la vanguardia.La otra opción sería acceder a un servicio de búsqueda como WhatIsMyIp.com . Estos chicos le devolverán su dirección IP del mundo real. Esto también es algo que puede configurar fácilmente con un script Perl en un servidor local si lo prefiere. Creo que unas 3 líneas de código para generar la IP remota desde% ENV deberían cubrirlo.
fuente
io = IO.popen('hostname') hostname = io.readlines io = IO.popen('ifconfig') ifconfig = io.readlines ip = ifconfig[11].scan(/\ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\ /)
El par de respuestas se
require 'socket'
ve bien. Los que tienen request.blah_blah_blah asumen que estás usando Rails.IO debería estar disponible todo el tiempo. El único problema con este script sería que si
ifconfig
se genera en una mansión diferente en sus sistemas, entonces obtendría resultados diferentes para la IP. La búsqueda de nombre de host debe ser sólida como Sears.fuente
prueba: Request.remote_ip
Actualización: Vaya, lo siento, leí mal la documentación.
fuente