Frage

Ich pflege gerade eine Ruby on Rails-App und suche nach einer einfachen Möglichkeit, den Hostnamen oder die IP-Adresse der Box zu finden, auf der ich mich befinde (da es sich um eine VM handelt und neue Instanzen möglicherweise andere Hostnamen oder IP-Adressen haben). .Gibt es eine schnelle und einfache Möglichkeit, dies in Ruby on Rails zu tun?

Bearbeiten:Die Antwort unten ist richtig, aber die Klarstellung, die Craig gegeben hat, ist nützlich (siehe auch den bereitgestellten Link in der Antwort):

Der [unten] Code stellt keine Verbindung her und sendet keine Pakete (auf 64.233.187.99, was Google ist).Da UDP ein staatenloser Protokoll ist Connect () macht lediglich einen Systemaufruf, der herausstellt, wie die Pakete basierend auf der Adresse und an welcher Schnittstelle (und damit IP -Adresse) sie gebunden werden sollen.ADDR () gibt ein Array zurück, das die Familie (AF_Inet), den lokalen Port und die lokale Adresse (die wir wollen) des Sockets enthält.

War es hilfreich?

Lösung

Aus coderr.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"

Andere Tipps

Hostname

Eine einfache Möglichkeit, den Hostnamen in Ruby abzurufen, ist:

require 'socket'
hostname = Socket.gethostname

Der Haken daran ist, dass dies davon abhängt, dass der Host seinen eigenen Namen kennt, da er entweder den verwendet gethostname oder uname Systemaufruf, daher wird es bei dem ursprünglichen Problem nicht funktionieren.

Funktionell ist dies identisch mit der hostname antworten, ohne ein externes Programm aufzurufen.Abhängig von der Konfiguration der Maschine kann der Hostname vollständig qualifiziert sein oder auch nicht.


IP Adresse

Seit Ruby 1.9 können Sie auch die Socket-Bibliothek verwenden, um eine Liste lokaler Adressen abzurufen. ip_address_list gibt ein Array von zurück AddrInfo Objekte.Wie Sie daraus auswählen, hängt davon ab, was Sie tun möchten und wie viele Schnittstellen Sie haben. Hier ist jedoch ein Beispiel, bei dem einfach die erste Nicht-Loopback-IPV4-IP-Adresse als Zeichenfolge ausgewählt wird:

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

Versuche dies:

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

Ein Server verfügt normalerweise über mehr als eine Schnittstelle, mindestens eine private und eine öffentliche.

Da sich alle Antworten hier auf dieses einfache Szenario beziehen, ist es sinnvoller, Socket nach dem Strom zu fragen ip_address_list() wie 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

Beide geben ein Addrinfo-Objekt zurück. Wenn Sie also eine Zeichenfolge benötigen, können Sie das verwenden ip_address() Methode, wie in:

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

Sie können ganz einfach die passendere Lösung für Ihren Fall finden, indem Sie die Addrinfo-Methoden ändern, die zum Filtern der erforderlichen Schnittstellenadresse verwendet werden.

Die hier verwendete IP-Adresse ist die von Google, Sie können jedoch jede erreichbare IP-Adresse verwenden.

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

Am einfachsten ist host_with_port in controller.rb

host_port= request.host_with_port

Die akzeptierte Antwort funktioniert, aber Sie müssen für jede Anfrage einen Socket erstellen und es funktioniert nicht, wenn sich der Server in einem lokalen Netzwerk befindet und/oder nicht mit dem Internet verbunden ist.Ich glaube, dass das Folgende immer funktionieren wird, da es den Anforderungsheader analysiert.

request.env["SERVER_ADDR"]

Setzen Sie den hervorgehobenen Teil in Backticks:

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

Oder nur request.host wenn es dir egal ist, ob es eine IP ist oder nicht.

Ähnlich wie die Antwort mit hostname, mit der externen uname Befehl unter UNIX/LINUX:

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

Für die verwendeten IP -Adressen (Ihr Computer kann über mehrere Netzwerkschnittstellen verfügen) können Sie so etwas verwenden:

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

Sie werden wahrscheinlich feststellen, dass auf jedem Computer mehrere IP-Adressen vorhanden sind (127.0.0.1, 192.168.0.1 usw.).Wenn Sie *NIX als Betriebssystem verwenden, würde ich die Verwendung empfehlen hostname, und anschließend eine DNS-Suche ausführen.Sie sollten in der Lage sein, /etc/hosts zu verwenden, um den lokalen Hostnamen zu definieren, der in die IP-Adresse für diesen Computer aufgelöst werden soll.Unter Windows gibt es ähnliche Funktionen, aber ich habe sie nicht verwendet, da Windows 95 auf dem neuesten Stand war.

Die andere Möglichkeit wäre, einen Suchdienst wie z. B. aufzurufen WhatIsMyIp.com.Diese Leute geben Ihnen Ihre echte IP-Adresse zurück.Wenn Sie möchten, können Sie dies auch ganz einfach mit einem Perl-Skript auf einem lokalen Server einrichten.Ich glaube, dass etwa drei Codezeilen zur Ausgabe der Remote-IP von %ENV ausreichen sollten.

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

Das Paar antwortet mit require 'socket' gut aussehen.Diejenigen mit Request.blah_blah_blah gehen davon aus, dass Sie Rails verwenden.

IO sollte jederzeit verfügbar sein.Das einzige Problem mit diesem Skript wäre, dass wenn ifconfig auf Ihren Systemen anders ausgegeben wird, dann würden Sie unterschiedliche Ergebnisse für die IP erhalten.Die Suche nach dem Hostnamen sollte „Sears“ lauten.

versuchen: Request.remote_ip

remote_ip()

Bestimmen Sie die ursprüngliche IP-Adresse.Remote_ADDR ist der Standard, fällt aber fehl, wenn der Benutzer hinter einem Proxy steht.Http_client_ip und/oder http_x_forwarded_for werden von proxies gesetzt.Http_x_forwarded_for kann bei mehreren angeketteten Proxies eine Kommando-Liste sein;Die letzte Adresse, die nicht vertrauenswürdig ist, ist die Ursprungs -IP.

Aktualisieren:Hoppla, tut mir leid, dass ich die Dokumentation falsch gelesen habe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top