रूबी में रूबी में होस्टनाम या आईपी प्राप्त करना


80

मैं रेल्स ऐप पर एक रूबी बनाए रखने की प्रक्रिया में हूं और मैं उस बॉक्स के होस्टनाम या आईपी पते को खोजने का एक आसान तरीका ढूंढ रहा हूं (क्योंकि यह एक वीएम है और नए उदाहरणों में अलग-अलग होस्टनाम या आईपी पते हो सकते हैं) । क्या रूबी ऑन रेल्स में ऐसा करने का एक त्वरित और आसान तरीका है?

संपादित करें: नीचे दिया गया उत्तर सही है लेकिन प्रदान किया गया स्पष्टीकरण क्रेग उपयोगी है (उत्तर में लिंक भी देखें):

[नीचे] कोड एक कनेक्शन नहीं बनाता है या कोई पैकेट नहीं भेजता है (64.233.187.99 जो Google है)। चूंकि यूडीपी एक स्टेटलेस प्रोटोकॉल कनेक्ट है () केवल एक सिस्टम कॉल करता है, जो यह पता लगाता है कि एड्रेस के आधार पर पैकेट को कैसे रूट किया जाए और किस इंटरफेस (और इसलिए आईपी एड्रेस) से इसे बाइंड किया जाए। Addr () एक सरणी देता है जिसमें परिवार (AF_INET), स्थानीय पोर्ट और स्थानीय पता (जो हम चाहते हैं) शामिल हैं।

जवाबों:


50

से 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"

1
@ user422543 उपरोक्त प्रश्न में संपादित प्रति, आईपी पते Google के हैं।
Topher Fangio

138

होस्ट का नाम

रूबी में केवल होस्टनाम प्राप्त करने का एक सरल तरीका है:

require 'socket'
hostname = Socket.gethostname

पकड़ यह है कि यह मेजबान को अपने स्वयं के नाम को जानने पर निर्भर करता है क्योंकि यह या तो gethostnameया unameसिस्टम कॉल का उपयोग करता है , इसलिए यह मूल समस्या के लिए काम नहीं करेगा।

कार्यात्मक रूप से यह hostnameबाहरी प्रोग्राम को लागू किए बिना, उत्तर के समान है । मशीन के कॉन्फ़िगरेशन के आधार पर होस्टनाम पूरी तरह से योग्य हो सकता है या नहीं भी हो सकता है।


आईपी ​​पता

माणिक 1.9 के बाद से, आप स्थानीय पते की सूची प्राप्त करने के लिए सॉकेट लाइब्रेरी का उपयोग कर सकते हैं। AddrInfo ऑब्जेक्ट्स ip_address_listकी एक सरणी देता है । आप इसे कैसे चुनते हैं, इस पर निर्भर करेगा कि आप क्या करना चाहते हैं और आपके पास कितने इंटरफेस हैं, लेकिन यहां एक उदाहरण है जो स्ट्रिंग के रूप में पहले गैर-लूपबैक आईपीवी 4 आईपी पते का चयन करता है:

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

Socket.gethostname हमेशा FQDN को वापस नहीं करता है। यदि FQDN वांछित है, तो 'hostname.strip' का उपयोग करना अधिक विश्वसनीय हो सकता है।
ट्रैविस भालू

सॉकेट। gethostname जाहिरा तौर पर हमेशा स्थिर नहीं होता है, टिप्पणियाँ देखें stackoverflow.com/q/14112955/32453
rogerdpack

आधिकारिक डॉक्टर पृष्ठ: ruby-doc.org/stdlib/libdoc/socket/rdoc/…
HarlemSquirrel

24

इसे इस्तेमाल करे:

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

4
मुझे शुद्धता के लिए सॉकेट.गेटहोस्टनाम पसंद है, लेकिन एक ऐसी प्रणाली पर एक सरल खोज के लिए जहां आप जानते हैं कि hostnameकाम करने जा रहा है, आप इसे सरलता के लिए नहीं हरा सकते हैं
डेव स्माइली

आप भी कर सकते हैं uname -n.sub (/\..*/, '')
Tilo

13

एक सर्वर में आमतौर पर एक से अधिक इंटरफ़ेस होते हैं, कम से कम एक निजी और एक सार्वजनिक।

चूँकि यहाँ सभी उत्तर इस सरल परिदृश्य के साथ काम करते हैं, एक साफ-सुथरा तरीका यह है कि सॉकेट को वर्तमान के लिए कहा जाए 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 विधियों को बदलते हुए अपने मामले के लिए अधिक उपयुक्त समाधान आसानी से निकाल सकते हैं।


9

यहाँ उपयोग किया गया यह IP पता Google का है, लेकिन आप किसी भी सुलभ IP का उपयोग कर सकते हैं।

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

8

host_with_portनियंत्रक में सबसे सरल है

host_port= request.host_with_port

2
नकारात्मक पक्ष यह है कि आपको अनुरोध तक पहुंचने के लिए नियंत्रक में रहना होगा .. लेकिन अच्छा विचार है!
तिलो

ऐसा लगता है कि अन्य उत्तर सिर्फ हैक हैं, जबकि यह इसे सही तरीके से करता है। यह उनके नीचे क्यों दफन है?
tbodt

2

स्वीकृत उत्तर काम करता है लेकिन आपको हर अनुरोध के लिए एक सॉकेट बनाना होगा और यह काम नहीं करेगा यदि सर्वर स्थानीय नेटवर्क पर है और / या इंटरनेट से जुड़ा नहीं है। नीचे, मेरा मानना ​​है कि अनुरोध शीर्षलेख को पार्स करने के बाद से यह हमेशा काम करेगा।

request.env["SERVER_ADDR"]

3
ओपी ने वास्तव में यह नहीं कहा कि उनके पास उस अनुरोध वस्तु तक पहुंच है जहां उन्हें आईपी पते की आवश्यकता है। सॉकेट आधारित समाधान अधिक सामान्य हैं
क्रिस मैकॉले जूल

2

हाइलाइट किए गए हिस्से को बैकटिक्स में रखें:

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

या बस request.hostअगर आपको परवाह नहीं है कि यह एक आईपी है या नहीं।


2

UNIX / LINUX पर hostnameबाहरी unameकमांड का उपयोग करते हुए उत्तर के समान :

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

उपयोग में आईपी पते के लिए (आपकी मशीन में कई नेटवर्क इंटरफेस हो सकते हैं), आप इस तरह से कुछ का उपयोग कर सकते हैं:

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

1

आप प्रत्येक मशीन (127.0.0.1, 192.168.0.1, आदि) पर कई आईपी पते होने की संभावना पाएंगे। यदि आप अपने OS के रूप में * NIX का उपयोग कर रहे हैं, तो मैं सुझाव दूंगा hostname, और फिर उस पर एक DNS लुक चला रहा हूं । उस मशीन के आईपी पते का समाधान करने के लिए आपको स्थानीय होस्टनाम को परिभाषित करने के लिए / etc / मेजबानों का उपयोग करने में सक्षम होना चाहिए। विंडोज पर समान कार्यक्षमता है, लेकिन मैंने इसका उपयोग नहीं किया है क्योंकि विंडोज 95 रक्तस्राव के किनारे था।

अन्य विकल्प व्हाट्सऐप.कॉम जैसी लुकअप सेवा को हिट करना होगा । ये लोग आपके वास्तविक दुनिया के IP पते को आपको वापस भेज देंगे। यह भी कुछ है जिसे आप आसानी से किसी स्थानीय सर्वर पर पर्ल स्क्रिप्ट के साथ सेटअप कर सकते हैं। मेरा मानना ​​है कि% ENV से दूरस्थ IP को आउटपुट करने के लिए कोड की 3 पंक्तियों या तो आपको कवर करना चाहिए।


अगर कोई बाहरी इंटरनेट नहीं है, तो WhatIsMyIP.com काम नहीं करेगा।
टीन मैन

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 वाले लोग मानते हैं कि आप रेल का उपयोग कर रहे हैं।

आईओ हर समय उपलब्ध होना चाहिए। इस स्क्रिप्ट के साथ एकमात्र समस्या यह होगी कि यदि ifconfigआपके सिस्टम पर एक अलग मनोर में आउटपुट होता है, तो आपको आईपी के लिए अलग-अलग परिणाम मिलेंगे। होस्टनाम लुक सियर्स के रूप में ठोस होना चाहिए।


0

कोशिश करें: Request.remote_ip

दूरदराज़ के आई. पी()

IP पते की उत्पत्ति का निर्धारण करें। REMOTE_ADDR मानक है लेकिन विफल रहेगा यदि उपयोगकर्ता एक प्रॉक्सी के पीछे है। HTTP_CLIENT_IP और / या HTTP_X_FORWARDED_FOR प्रॉक्सी द्वारा निर्धारित किए जाते हैं, इसलिए यदि REMOTE_ADDR प्रॉक्सी है तो इनकी जांच करें। HTTP_X_FORWARDED_FOR कई जंजीरों वाले परदे के पीछे अल्पविराम वाली सूची हो सकती है; अंतिम पता जिस पर भरोसा नहीं किया जाता है वह मूल आईपी है।

अपडेट: ओह, माफ करना, मैंने दस्तावेज को गलत बताया।


यह आपको Rails ऐप के लिए अनुरोध जारी करने वाले उपयोगकर्ता का IP पता देता है, न कि Rails ऐप चलाने वाली मशीन का IP पता।
jsears
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.