Obter o nome da máquina ou o IP em Ruby nos carris

Estou no processo de manter um aplicativo Ruby on Rails e estou procurando uma maneira fácil de encontrar o nome ou endereço IP da caixa em que estou (uma vez que é um VM e novas instâncias podem ter diferentes nomes de host ou endereços IP). Existe uma maneira rápida e fácil de fazer isso em Ruby on Rails?

editar: a resposta abaixo está correcta, mas o esclarecimento que Craig forneceu é útil (Ver também a ligação fornecida na resposta):

o código [abaixo] não faz um ligação ou envio pacotes (para 64.233.187.99 que é o google). Uma vez que UDP é uma conexão de Protocolo apátrida() apenas faz uma chamada de sistema que descobre como encaminhar os pacotes baseado no endereço e no que interface (e, portanto, endereço IP) deve ligar-se a isso. o addr () devolve um lista que contém a família (AF_INET), porto local e endereço local (que é o que queremos) do socket.

Author: True Soft, 2008-09-04

12 answers

De 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"
 46
Author: titanous, 2008-09-04 00:37:30

Nome da máquina

Uma maneira simples de obter o nome da máquina em Ruby é:

require 'socket'
hostname = Socket.gethostname

A captura é que isto depende do host saber o seu próprio nome porque ele usa a chamada do sistema {[[2]} ou uname, por isso não vai funcionar para o problema original.

Funcionalmente, isto é idêntico à resposta hostname, sem invocar um programa externo. O nome da máquina pode ou não ser totalmente qualificado, dependendo da configuração da máquina.

IP Endereço

Desde o ruby 1.9, você também pode usar a Biblioteca Socket para obter uma lista de endereços locais. ip_address_list devolve uma lista de objectos AddrInfo . A forma como você escolhe dele dependerá do que você deseja fazer e de quantas interfaces você tem, mas aqui está um exemplo que simplesmente seleciona o primeiro endereço IP não-loopback IPV4 como um texto:

require 'socket'
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
 129
Author: Tim Peters, 2014-12-03 17:30:23

Tenta isto:

host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host               # Output the hostname
 22
Author: John Topley, 2011-08-04 23:33:04

Um servidor normalmente tem mais de uma interface, pelo menos uma privada e uma pública.

Uma vez que todas as respostas aqui lidam com este cenário simples, uma maneira mais limpa é pedir ao Socket a actual {[[2]} como em:

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

Ambos devolvem um objecto Addrinfo, por isso, se precisar de um texto, pode usar o método ip_address(), como em:

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

Você pode facilmente resolver a solução mais adequada para o seu caso, alterando os métodos Addrinfo usados para filtrar a interface necessária endereco.

 10
Author: Claudio Floreani, 2014-12-03 17:33:10

Este endereço IP aqui usado é do Google, mas você pode usar qualquer IP acessível.

require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
 9
Author: D-D-Doug, 2011-02-17 14:23:31

O mais simples é host_with_port no comando.rb

host_port= request.host_with_port
 7
Author: Salil, 2014-12-03 17:33:48

A resposta aceita funciona mas você tem que criar um socket para cada pedido e não funciona se o servidor está em uma rede local e/ou não conectado à internet. O abaixo, eu acredito que sempre funcionará uma vez que está processando o cabeçalho do pedido.

request.env["SERVER_ADDR"]
 2
Author: hacintosh, 2011-01-18 16:16:32

Coloque a parte destacada em retoques:

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

Ou apenas request.host Se não te importas se é um IP ou não.

 2
Author: Sai, 2013-06-05 16:07:30

Semelhante à resposta usando hostname, usando o comando externo uname no UNIX / LINUX:

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

Para os endereços IP em uso (a sua máquina pode ter várias interfaces de rede), dava-te jeito algo assim.

 # 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']
 2
Author: Tilo, 2014-12-03 17:30:52

É provável que tenha vários endereços IP em cada máquina (127.0. 0. 1, 192. 168. 0. 1, etc.). Se está a usar o *NIX como seu SO, eu sugiro o uso de {[[0]}, e depois fazer uma pesquisa DNS sobre isso. Você deve ser capaz de USAR /etc/hosts para definir o nome da máquina local para resolver para o endereço IP dessa máquina. Existe uma funcionalidade semelhante no Windows, mas não a uso desde que o Windows 95 era o limite de hemorragia.

A outra opção seria aceder a um serviço de pesquisa. tipo WhatIsMyIp.com estes tipos devolvem-te o teu endereço de IP do mundo real. Isto também é algo que você pode facilmente configurar com um script Perl em um servidor local, se preferir. Acredito que 3 linhas de código para enviar o IP remoto de %ENV devem cobrir você.
 1
Author: Jack M., 2008-09-03 22:18:45
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}\ /)

O par de respostas com require 'socket' parece bem. Aqueles com pedido.blah_blah_blah assume que estás a usar Carris.

Deve estar sempre disponível. O único problema com este script seria que se ifconfig é a saída em um solar diferente em seus sistemas, então você obteria resultados diferentes para o IP. A aparência do nome da máquina deverá ser sólida como Sears.

 1
Author: Kevin Krauss, 2014-12-03 17:31:44

Tentar: Pedido.remote_ip

Remote_ip ()

Determinar o endereço IP de origem. O REMOTE_ADDR é o padrão, mas irá falha se o usuário estiver por trás de um proxy. HTTP_ CLIENT_ IP e/ou HTTP_ x_ FORWARDED_ for are set by proxies so check for these if REMOTE_ADDR é um proxy. HTTP_X_FORWARDED_FOR pode ser uma vírgula delimitada lista no caso de vários proxies acorrentados; o último endereço que não é confiável é a origem PI.

Actualizar: Desculpa ter lido mal a documentação.

 0
Author: Craig, 2015-03-16 13:08:45