2011-02-17 17 views
14

Necesito obtener mi IP (que es DHCP). Yo uso este en mi environment.rb:Ruby: obtener IP (nix) local

LOCAL_IP = `ifconfig wlan0`.match(/inet addr:(\d*\.\d*\.\d*\.\d*)/)[1] || "localhost" 

pero ¿hay rubyway o solución más limpia?

+0

Puede haber varias direcciones IP locales. Comúnmente, la dirección a usar (por ejemplo, para abrir un socket de escucha) se especifica a través de un archivo de configuración. – Thomas

+0

Necesito la dirección wlan0 inet. Lo recibo a través de DHCP desde mi enrutador wifi. Entonces, para mi entorno de desarrollo necesito establecer una nueva IP cada vez que me vuelva a conectar a mi enrutador. Así que ahora quiero obtenerlo automáticamente del sistema. Utilizo el comando Unix para obtenerlo y funciona bien, pero ahora estoy buscando más solución de rubyway. – fl00r

+0

Posible duplicación: http://stackoverflow.com/questions/42566/getting-the-hostname-or-ip-in-ruby-on-rails – steenslag

Respuesta

29

Un servidor normalmente tiene más de una interfaz, por lo menos una privada y una pública.

Puesto que todas las respuestas aquí frente a este escenario simple, una forma más limpia es preguntar zócalo de 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 

Tanto devuelve un objeto Addrinfo, así que si necesitas una cadena Puede utilizar el método ip_address(), como en:

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil? 

Se puede trabajar fácilmente la solución más adecuada a su caso el cambio de métodos addrinfo utilizados para filtrar la dirección de la interfaz requerida.

+3

BTW, creo que esto no está disponible en v1.8 – nhed

+0

Completitud de Fo, para obtener la dirección IP: Socket.ip_address_list.detect {| intf | intf.ipv4_private?}. getnameinfo [0] –

+0

Como nota, ip_address_list se introdujo en 1.9.x, parece – rogerdpack

11
require 'socket' 

def local_ip 
    orig = Socket.do_not_reverse_lookup 
    Socket.do_not_reverse_lookup =true # turn off reverse DNS resolution temporarily 
    UDPSocket.open do |s| 
    s.connect '64.233.187.99', 1 #google 
    s.addr.last 
    end 
ensure 
    Socket.do_not_reverse_lookup = orig 
end 

puts local_ip 

Encontrado here.

+0

Este método se bloqueará si la máquina vive en una LAN que no se conecta a la WAN. Me encuentro con un problema de bloqueo en el caso. – qichunren

+0

1.8.x amistoso, gracias! – rogerdpack

7

Aquí está una pequeña modificación de la solución de steenslag

require "socket" 
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last} 
+2

¿Por qué es eso una mejora? @steenslag se ejecutará más rápido ya que deshabilita las búsquedas DNS, el código más corto no siempre es mejor – nhed

Cuestiones relacionadas