15

I need to get my IP (that is DHCP). I use this in my environment.rb:

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

But is there rubyway or more clean solution?

Chris McCauley
  • 25,824
  • 8
  • 48
  • 65
fl00r
  • 82,987
  • 33
  • 217
  • 237
  • There might be multiple local IP addresses. Commonly, the address to use (e.g. for opening a listening socket) is specified through a configuration file. – Thomas Feb 17 '11 at 13:24
  • I need wlan0 inet address. I get it through DHCP from my wifi router. So for my development envirement I need to set new IP each time I reconnect to my router. So now I want to get it auto from system. I use unix command to get it and it works fine, but now I am looking for more rubyway solution. – fl00r Feb 17 '11 at 13:34
  • Possible duplication: http://stackoverflow.com/questions/42566/getting-the-hostname-or-ip-in-ruby-on-rails – steenslag Feb 17 '11 at 14:00
  • yep. it's duplicate. but I can't delete it – fl00r Feb 17 '11 at 14:05

3 Answers3

31

A server typically has more than one interface, at least one private and one public.

Since all the answers here deal with this simple scenario, a cleaner way is to ask Socket for the current ip_address_list() as in:

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

Both returns an Addrinfo object, so if you need a string you can use the ip_address() method, as in:

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

You can easily work out the more suitable solution to your case changing Addrinfo methods used to filter the required interface address.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Claudio Floreani
  • 2,441
  • 28
  • 34
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

Found here.

steenslag
  • 79,051
  • 16
  • 138
  • 171
  • This method will crash if the machine live in LAN which not connect to WAN. I meet crash problem in the case. – qichunren Dec 15 '13 at 12:37
7

Here is a small modification of steenslag's solution

require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
Doug
  • 563
  • 4
  • 10
  • 3
    Why is that an improvement? @steenslag will run faster as it disables DNS lookups, shorter code is not always better – nhed Jan 12 '15 at 15:14