关于网络:在Ruby on Rails中获取主机名或IP

关于网络:在Ruby on Rails中获取主机名或IP

Getting the Hostname or IP in Ruby on Rails

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

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

The [below] code does NOT make a
connection or send any packets (to
64.233.187.99 which is google). Since UDP is a stateless protocol connect()
merely makes a system call which
figures out how to route the packets
based on the address and what
interface (and therefore IP address)
it should bind to. addr() returns an
array containing the family (AF_INET),
local port, and local address (which
is what we want) of the socket.


主机名

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

1
2
require 'socket'
hostname = Socket.gethostname

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

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

IP地址

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

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

从coderrr.wordpress.com:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
2
3
host = `hostname`.strip # Get the hostname from the shell and removing trailing \

puts host               # Output the hostname

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

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

1
2
3
4
5
6
7
8
9
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()方法,如下所示:

1
ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

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


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

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

最简单的是controller.rb中的host_with_port

1
host_port= request.host_with_port

与使用hostname的答案类似,在UNIX / LINUX上使用外部uname命令:

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

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

1
2
3
4
5
6
7
 # 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']

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

1
request.env["SERVER_ADDR"]

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

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

如果您不在乎它是否是IP,则只需request.host


1
2
3
4
5
6
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保持一致。


您可能会发现自己在每台计算机上都有多个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来覆盖您。


尝试:Request.remote_ip

remote_ip()

Determine originating IP address. REMOTE_ADDR is the standard but will
fail if the user is behind a proxy. HTTP_CLIENT_IP and/or
HTTP_X_FORWARDED_FOR are set by proxies so check for these if
REMOTE_ADDR is a proxy. HTTP_X_FORWARDED_FOR may be a comma- delimited
list in the case of multiple chained proxies; the last address which
is not trusted is the originating IP.

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


推荐阅读