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