2008-09-03 17 views
73

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

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

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

उत्तर

45

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" 
+0

धन्यवाद एक गुच्छा! यह मेरे लिए पूरी तरह से काम करता है :-) –

+1

@ टोफरफैंगियो जो यह आईपी 64.233.187.99 है? –

+1

@ user422543 उपरोक्त प्रश्न में संपादित किए गए अनुसार, आईपी पता Google से संबंधित है। –

0

कोशिश: Request.remote_ip

remote_ip()

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

अद्यतन: ओह, क्षमा करें, मैंने प्रलेखन को गलत तरीके से पढ़ा।

+0

यह आपको रेल ऐप के लिए अनुरोध जारी करने वाले उपयोगकर्ता का आईपी पता देता है, न कि रेल ऐप चलाने वाली मशीन का आईपी पता। – jsears

22

इस प्रयास करें:

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

मुझे शुद्धता के लिए सॉकेट.gethostname पसंद है, लेकिन एक सिस्टम पर एक साधारण लुकअप के लिए जहां आप जानते हैं कि 'होस्टनाम' काम करने जा रहा है, आप सादगी –

+0

के लिए इसे हरा नहीं सकते हैं आप 'uname -n'.sub भी कर सकते हैं (/\..*/, '') – Tilo

1

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

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

+0

यदि कोई बाहरी इंटरनेट एक्सेस नहीं है तो WhatIsMyIP.com काम नहीं करेगा। –

124

होस्टनाम

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

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

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


आईपी पता

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

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

सॉकेट.getहोस्टनाम हमेशा एफक्यूडीएन वापस नहीं करता है। FQDN वांछित होने पर 'hostname'strip का उपयोग करना अधिक विश्वसनीय हो सकता है। –

+0

सॉकेट। gethostname स्पष्ट रूप से हमेशा स्थिर नहीं है, टिप्पणियां देखें http://stackoverflow.com/q/14112955/32453 – rogerdpack

2

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

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

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

7

सरल controller.rb में host_with_port है

host_port= request.host_with_port 
+1

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

+0

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

2

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

request.env["SERVER_ADDR"] 
+3

ओपी वास्तव में यह नहीं कहता था कि उस बिंदु पर अनुरोध ऑब्जेक्ट तक पहुंच थी जहां उसे आईपी पते की आवश्यकता थी। सॉकेट आधारित समाधान अधिक सामान्य हैं –

9

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

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

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

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

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 आपके सिस्टम पर एक अलग मनोरंजक में आउटपुट है, तो आपको आईपी के लिए अलग-अलग परिणाम मिलेंगे। होस्टनाम लुकअप सीअर्स के रूप में ठोस होना चाहिए।

2

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'] 
संबंधित मुद्दे