在Ruby on Rails中获取主机名或IP


80

我正在维护Ruby on Rails应用程序,并且正在寻找一种简单的方法来查找我所在盒子的主机名或IP地址(因为它是VM,并且新实例可能具有不同的主机名或IP地址) 。在Ruby on Rails中有快速简便的方法吗?

编辑:下面的答案是正确的,但是提供的澄清Craig很有用(另请参见答案中提供的链接):

[以下]代码不会建立连接或发送任何数据包(至Google的64.233.187.99)。由于UDP是无状态协议,所以connect()仅进行系统调用,该系统调用根据地址和绑定的接口(以及IP地址)确定如何路由数据包。addr()返回一个数组,其中包含套接字的族(AF_INET),本地端口和本地地址(这是我们想要的)。

Answers:


50

来自coderrr.wordpress.com

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
    s.addr.last
  end
ensure
  Socket.do_not_reverse_lookup = orig
end

# irb:0> local_ip
# => "192.168.0.127"

1
@ user422543根据上述问题的修改,该IP地址属于Google。
Topher Fangio 2013年

137

主机名

在Ruby中获取主机名的一种简单方法是:

require 'socket'
hostname = Socket.gethostname

问题在于,这依赖于主机知道自己的名称,因为主机使用gethostnameuname系统调用,因此对于原始问题将不起作用。

从功能上讲,这与hostname答案相同,而无需调用外部程序。主机名可能是完全限定的,也可能不是完全限定的,具体取决于计算机的配置。


IP地址

从ruby 1.9开始,您还可以使用Socket库获取本地地址列表。 ip_address_list返回AddrInfo对象的数组。您如何选择它取决于您要做什么以及拥有多少接口,但是以下示例仅选择第一个非环回IPV4 IP地址作为字符串:

require 'socket'
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address

Socket.gethostname并不总是返回FQDN。如果需要FQDN,则使用'hostname'.strip可能更可靠。
特拉维斯·贝尔

插座。gethostname显然并不总是稳定的,请参见注释stackoverflow.com/q/14112955/32453
rogerdpack


24

试试这个:

host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host               # Output the hostname

4
我喜欢Socket.gethostname的纯洁性,但是对于在您知道hostname将要工作的系统上进行的简单查找,就无法简单地击败它
Dave Smylie

您也可以做uname -n.sub(/\..*/,'')–
Tilo

13

一台服务器通常具有多个接口,至少一个专用接口和一个公用接口。

由于这里的所有答案都是针对这种简单情况的,因此一种更干净的方法是向Socket索要电流,ip_address_list()如下所示:

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

两者都返回一个Addrinfo对象,因此,如果您需要一个字符串,则可以使用该ip_address()方法,如下所示:

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

您可以轻松地通过更改用于过滤所需接口地址的Addrinfo方法来找到更适合您的情况的解决方案。


9

这里使用的IP地址是Google的,但您可以使用任何可访问的IP。

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

8

最简单的是host_with_portcontroller.rb

host_port= request.host_with_port

2
缺点是您必须在控制器中才能访问该请求。但是好主意!
提洛

似乎其他答案只是黑客,而这样做是正确的。为什么要埋在他们下面?
tbodt

2

可接受的答案有效,但是您必须为每个请求创建一个套接字,并且如果服务器位于本地网络上和/或未连接到Internet,则套接字无效。我相信下面的内容将一直有效,因为它正在解析请求标头。

request.env["SERVER_ADDR"]

3
OP实际上并没有说他们在需要IP地址时可以访问请求对象。基于套接字的解决方案是更通用的
克里斯·麦考利

2

将突出显示的部分放在反引号中:

`dig #{request.host} +short`.strip # dig gives a newline at the end

或者只是request.host不管您是否在乎它是否是IP。


2

与使用答案相似hostnameuname在UNIX / LINUX上使用外部命令:

hostname = `uname -n`.chomp.sub(/\..*/,'')  # stripping off "\n" and the network name if present

对于正在使用的IP地址(您的计算机可能具有多个网络接口),您可以使用以下方式:

 # 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']

1

您可能会发现自己在每台计算机上都有多个IP地址(127.0.0.1、192.168.0.1等)。如果您使用* NIX作为操作系统,建议您使用hostname,然后在其上运行DNS。您应该能够使用/ etc / hosts定义本地主机名,以解析为该计算机的IP地址。Windows上有类似的功能,但是由于Windows 95是最前沿,所以我没有使用过。

另一个选择是点击类似WhatIsMyIp.com的查找服务。这些家伙会把您的真实IP地址发给您。如果您愿意,也可以使用本地服务器上的Perl脚本轻松设置此设置。我相信3%左右的代码可以从%ENV输出远程IP来覆盖您。


如果没有外部互联网访问,WhatIsMyIP.com将无法正常工作。
Tin Man

1
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}\ /)

几个答案require 'socket'看起来不错。具有request.blah_blah_blah的用户假定您正在使用Rails。

IO应该一直可用。该脚本的唯一问题是,如果ifconfig在您的系统上以不同的方式输出,那么对于IP,您将获得不同的结果。查找的主机名应与Sears保持一致。


0

尝试:Request.remote_ip

remote_ip()

确定原始IP地址。REMOTE_ADDR是标准,但是如果用户位于代理之后,它将失败。HTTP_CLIENT_IP和/或HTTP_X_FORWARDED_FOR由代理设置,因此请检查REMOTE_ADDR是否为代理。如果是多链代理,HTTP_X_FORWARDED_FOR可能是一个以逗号分隔的列表。最后一个不受信任的地址是原始IP。

更新:糟糕,对不起,我误读了文档。


这为您提供了向Rails应用程序发出请求的用户的IP地址,而不是运行Rails应用程序的计算机的IP地址。
jsears 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.