83

私はRubyonRailsアプリを保守している最中であり、使用しているボックスのホスト名またはIPアドレスを見つける簡単な方法を探しています(VMであり、新しいインスタンスのホスト名またはIPアドレスが異なる可能性があるため) 。Ruby on Railsでこれを行うための迅速で簡単な方法はありますか?

編集:以下の答えは正しいですが、クレイグが提供した説明は役に立ちます(答えの提供されたリンクも参照してください):

[下記]コードは、接続を確立したり、パケットを送信したりしません(googleである64.233.187.99に)。UDPはステートレスプロトコルであるため、connect()は、アドレスとバインドする必要のあるインターフェイス(したがってIPアドレス)に基づいてパケットをルーティングする方法を判断するシステムコールを作成するだけです。addr()は、ソケットのファミリ(AF_INET)、ローカルポート、およびローカルアドレス(必要なもの)を含む配列を返します。

4

12 に答える 12

141

ホスト名

Ruby でホスト名を取得する簡単な方法は次のとおりです。

require 'socket'
hostname = Socket.gethostname

gethostname問題は、これは、またはシステム コールのいずれかを使用するため、ホストが自身の名前を知っていることに依存しているunameため、元の問題では機能しないことです。

機能的には、これはhostname外部プログラムを呼び出さずに、答えと同じです。マシンの構成によっては、ホスト名が完全修飾されている場合とそうでない場合があります。


IPアドレス

ruby 1.9 から、ソケット ライブラリを使用してローカル アドレスの一覧を取得することもできます。 AddrInfoオブジェクトip_address_listの配列を返します。そこからどのように選択するかは、何をしたいのか、何個のインターフェイスがあるかによって異なりますが、次の例では、最初の非ループバック IPV4 IP アドレスを文字列として単純に選択しています。

require 'socket'
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
于 2009-10-08T04:00:29.610 に答える
51

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"
于 2008-09-04T00:37:30.987 に答える
25

これを試して:

host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host               # Output the hostname
于 2008-09-03T21:19:16.547 に答える
13

通常、サーバーには複数のインターフェイス (少なくとも 1 つのプライベートと 1 つのパブリック) があります。

ここでのすべての回答はこの単純なシナリオを扱っているため、よりクリーンな方法は、次のように 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 メソッドを変更することで、より適切なソリューションを簡単に見つけることができます。

于 2011-10-18T14:39:26.450 に答える
10

最も単純なのはhost_with_portcontroller.rbです

host_port= request.host_with_port
于 2010-07-14T13:54:09.850 に答える
9

ここで使用されているこのIPアドレスはGoogleのものですが、アクセス可能な任意のIPを使用できます。

require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
于 2011-02-17T14:23:31.130 に答える
3

UNIX/LINUX でhostname外部コマンドを使用して、 を使用した回答に似ています。uname

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']
于 2012-09-28T02:45:36.040 に答える
2

受け入れられた答えは機能しますが、リクエストごとにソケットを作成する必要があり、サーバーがローカルネットワーク上にある場合やインターネットに接続されていない場合は機能しません。以下は、リクエストヘッダーを解析しているため、常に機能すると思います。

request.env["SERVER_ADDR"]
于 2011-01-18T16:16:32.727 に答える
1

各マシンに複数の IP アドレス (127.0.0.1、192.168.0.1 など) があることに気付くでしょう。OS として *NIX を使用している場合は、 を使用しhostname、その上で DNS ルックアップを実行することをお勧めします。/etc/hosts を使用してローカル ホスト名を定義し、そのマシンの IP アドレスに解決できるはずです。Windows にも同様の機能がありますが、Windows 95 が最先端だったので使用していません。

もう 1 つのオプションは、WhatIsMyIp.comなどのルックアップ サービスにアクセスすることです。これらの人は、あなたの実世界の IP アドレスをあなたにキックバックします. これは、必要に応じて、ローカル サーバーで Perl スクリプトを使用して簡単にセットアップできるものでもあります。%ENV からリモート IP を出力する 3 行程度のコードでカバーできるはずです。

于 2008-09-03T22:18:45.140 に答える
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 のようにしっかりしている必要があります。

于 2011-11-17T21:23:16.280 に答える
0

試してください:Request.remote_ip

remote_ip()

発信元IPアドレスを決定します。REMOTE_ADDRが標準ですが、ユーザーがプロキシの背後にいる場合は失敗します。HTTP_CLIENT_IPおよび/またはHTTP_X_FORWARDED_FORはプロキシによって設定されるため、REMOTE_ADDRがプロキシであるかどうかを確認してください。HTTP_X_FORWARDED_FORは、複数のチェーンプロキシの場合、コンマ区切りのリストにすることができます。信頼されていない最後のアドレスは発信元IPです。

更新:おっと、申し訳ありませんが、ドキュメントを読み間違えました。

于 2008-09-03T21:06:22.787 に答える