Я поддерживаю приложение Ruby on Rails и ищу удобный способ найти имя хоста или IP-адрес поля, в котором я включен (так как виртуальная машина и новые экземпляры могут иметь разные имена хостов или IP-адреса). Есть ли быстрый и простой способ сделать это в Ruby on Rails?
Изменить: ответ ниже правильный, но пояснение, предоставленное Крейгом, полезно (см. также предоставленную ссылку в ответе):
Код [ниже] НЕ делает подключения или отправки любых пакетов ( 64.233.187.99, который является google). Поскольку UDP является протоколом без состояния connect() просто делает системный вызов, который определяет, как маршрутизировать пакеты на основе адреса и интерфейс (и, следовательно, IP-адрес) он должен привязываться. addr() возвращает массив, содержащий семейство (AF_INET), локальный порт и локальный адрес (который это то, что мы хотим) сокета.
Ответ 1
От 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"
Ответ 2
Hostname
Простой способ получить имя хоста в Ruby:
require 'socket'
hostname = Socket.gethostname
Ловушка заключается в том, что это зависит от хоста, зная его собственное имя, потому что оно использует системный вызов gethostname
или uname
, поэтому он не будет работать для исходной проблемы.
Функционально это идентично ответу hostname
, не вызывая внешнюю программу. Имя хоста может быть или не быть полностью квалифицированным, в зависимости от конфигурации машины.
IP-адрес
Так как ruby 1.9, вы также можете использовать библиотеку Socket для получения списка локальных адресов. ip_address_list
возвращает массив объектов AddrInfo. Как вы выберете его, это будет зависеть от того, что вы хотите сделать и от того, сколько интерфейсов у вас есть, но вот пример, который просто выбирает первый IP-адрес IP-адреса без петли в виде строки:
require 'socket'
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
Ответ 3
Попробуйте следующее:
host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host # Output the hostname
Ответ 4
Обычно сервер имеет несколько интерфейсов, по крайней мере один частный и один публичный.
Поскольку все ответы здесь касаются этого простого сценария, более чистый способ - спросить 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, используемые для фильтрации требуемого адреса интерфейса.
Ответ 5
Этот IP-адрес, используемый здесь, - это Google, но вы можете использовать любой доступный IP-адрес.
require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
Ответ 6
Simplest host_with_port
в контроллере .rb
host_port= request.host_with_port
Ответ 7
Поместите выделенную часть в backticks:
`dig #{request.host} +short`.strip # dig gives a newline at the end
Или просто request.host
, если вам все равно, является ли он IP или нет.
Ответ 8
Принятый ответ работает, но вам нужно создать сокет для каждого запроса, и он не работает, если сервер находится в локальной сети и/или не подключен к Интернету. Ниже, я считаю, всегда будет работать, поскольку он анализирует заголовок запроса.
request.env["SERVER_ADDR"]
Ответ 9
Как и в ответе, используя hostname
, используя внешнюю команду uname
в 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']
Ответ 10
Вероятно, у вас будет несколько IP-адресов на каждой машине (127.0.0.1, 192.168.0.1 и т.д.). Если вы используете * NIX в качестве ОС, я бы предложил использовать hostname
, а затем запустить DNS, чтобы посмотреть на это. Вы должны иметь возможность использовать /etc/hosts для определения локального имени хоста для разрешения на IP-адрес для этой машины. В Windows аналогичная функциональность, но я не использовал ее, так как Windows 95 была краем кровотечения.
Другой вариант - нажать на службу поиска, например WhatIsMyIp.com. Эти ребята откажут вам ваш реальный IP-адрес. Это также можно настроить с помощью Perl script на локальном сервере, если вы предпочитаете. Я считаю, что 3 строки или около того кода для вывода удаленного IP из% ENV должны покрыть вас.
Ответ 11
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 должен быть доступен все время. Единственная проблема с этим script заключается в том, что если ifconfig
выводится в другой усадьбе в ваших системах, вы получите разные результаты для IP. Взгляд хоста должен быть твердым, как Сирс.
Ответ 12
попробуйте: Request.remote_ip
remote_ip()
Определите исходный IP-адрес. REMOTE_ADDR является стандартным, но если пользователь находится за прокси-сервером. HTTP_CLIENT_IP и/или HTTP_X_FORWARDED_FOR устанавливаются прокси-серверами, поэтому проверьте их, если REMOTE_ADDR - прокси. HTTP_X_FORWARDED_FOR может быть разделенным запятыми список в случае нескольких целых прокси; последний адрес, который не является надежным источником IP.
Обновление:
К сожалению, я неправильно прочитал документацию.