2011-03-04 1 views
5

आप एक रूबी स्क्रिप्ट में एक सिस्टम कॉल का उपयोग करते हैं, तो आप इस तरह है कि आदेश के उत्पादन प्राप्त कर सकते हैं:क्या मुझे रूबी में सिस्टम कॉल से निरंतर आउटपुट मिल सकता है?

output = `ls` 
puts output 

है यही कारण है कि this question बारे में था।

लेकिन क्या सिस्टम कॉल के निरंतर आउटपुट दिखाने का कोई तरीका है? उदाहरण के लिए, अगर आप इस सुरक्षित प्रतिलिपि आदेश चला, SSH पर एक सर्वर से एक फ़ाइल प्राप्त करने के लिए:

scp [email protected]:remoteFile /some/local/folder/ 

... यह डाउनलोड की प्रगति के साथ सतत उत्पादन को दर्शाता है। लेकिन यह:

output = `scp [email protected]:remoteFile /some/local/folder/` 
puts output 

... उस आउटपुट को कैप्चर नहीं करता है।

मैं अपनी रूबी लिपि के अंदर से डाउनलोड की चल रही प्रगति कैसे दिखा सकता हूं?

+1

आप दो ओर्थोगोनल समस्याओं यहाँ था, क्योंकि SCP केवल डिफ़ॉल्ट रूप से टर्मिनलों के लिए आउटपुट, आप की जरूरत * SCP -v * – tokland

+0

@tokland - यह है कि यह उत्पादन डिबगिंग संदेशों को हो जाता है, लेकिन नहीं हस्तांतरण प्रगति है कि मैं देखना होगा अगर मैं सिर्फ अकेले scp भाग गया। मुझे लगता है कि उन्हें मानक आउटपुट पर नहीं जाना चाहिए, और मुझे उन्हें भेजने के लिए एसपीपी के लिए कोई विकल्प नहीं दिख रहा है। –

+0

स्पष्ट रूप से एसपीपी उस प्रगति की जानकारी को "इंटरैक्टिव टर्मिनल" भेजता है? सुनिश्चित नहीं है कि इसे कैप्चर कैसे करें ... –

उत्तर

9

प्रयास करें:

IO.popen("scp -v [email protected]:remoteFile /local/folder/").each do |fd| 
    puts(fd.readline) 
end 
+0

यह मानक आउटपुट संदेश प्राप्त करने के लिए काम करता है, लेकिन ऐसा लगता है कि ऐसा नहीं है जहां एसपीपी अपनी स्थानांतरण प्रगति भेज रहा है। तो मुझे लगता है कि मेरी समस्या अब एसपीपी के साथ है। –

+0

यह सवाल मैंने उत्तर दिया है - तथ्य यह है कि एसपीपी सामान्य आउटपुट नहीं करता है, यह एक अप्रत्याशित विस्तार साबित हुआ है। –

+0

नीचे मेरा जवाब देखें कि मैं रूबी मानक लाइब्रेरी से उस आउटपुट को कैसे प्राप्त कर सकता था। –

0

क्या आपने आईओ.popen के साथ प्रयास किया है? प्रक्रिया को अभी भी चल रहा है, जबकि आप आउटपुट को पढ़ने में सक्षम होना चाहिए और तदनुसार इसे पार्स करें।

3

मुझे लगता है कि आप SCP को संभालने के लिए (के रूप में एक खोल प्रक्रिया forking के खिलाफ) गहरे लाल रंग का मानक पुस्तकालय का उपयोग कर बेहतर भाग्य होगा। नेट :: एससीपी लाइब्रेरी (साथ ही पूरे नेट :: * लाइब्रेरीज़) पूर्ण फीचर्ड हैं और रिमोट कमांड को संभालने के लिए कैपिस्ट्रानो के साथ उपयोग की जाती हैं।

चेकआउट http://net-ssh.rubyforge.org/ जो उपलब्ध है, उसके लिए उपलब्ध है। stdout में

+0

यह वास्तव में आशाजनक लग रहा है! नेट-एसपीपी दस्तावेज यहां है: http://net-ssh.github.com/scp/v1/api/index.html इसके अलावा, यह ट्यूटोरियल दिखाता है कि स्थानांतरण के दौरान प्रगति कैसे आउटपुट करें: http: //ruby.about। com/od/ssh/ss/netscp_4.htm –

+0

यही वह है जो मैंने कर दिया। मैं स्क्रैप ऑब्जेक्ट को ब्लॉक पास करके डाउनलोड प्रगति का एक रनिंग काउंटर दिखाने में सक्षम था। पूरी लिपि के लिए मेरा जवाब देखें। –

0

रीडायरेक्ट कर रहा है stderr आप के लिए काम कर सकते हैं:

output = `scp [email protected]:remoteFile /some/local/folder/ 2>&1` 
puts output 

कि दोनों stderr और stdout पर कब्जा करना चाहिए। आप केवल दूर stdout फेंक कर stderr पर कब्जा कर सकते हैं:

output = `scp [email protected]:remoteFile /some/local/folder/ 2>&1 >/dev/null` 
puts output 

फिर आप IO.popen उपयोग कर सकते हैं।

2

टोकलैंड ने सवाल पूछा, जैसा कि मैंने पूछा था, लेकिन एडम का दृष्टिकोण जो मैंने समाप्त किया था। यहां मेरी पूर्ण लिपि थी, जो डाउनलोड बाइट्स की चल रही गिनती दिखाती है, और एक प्रतिशत भी पूर्ण होती है।

require 'rubygems' 
require 'net/scp' 
puts "Fetching file" 

# Establish the SSH session 
ssh = Net::SSH.start("IP Address", "username on server", :password => "user's password on server", :port => 12345) 

# Use that session to generate an SCP object 
scp = ssh.scp 

# Download the file and run the code block each time a new chuck of data is received 
scp.download!("path/to/file/on/server/fileName", "/Users/me/Desktop/") do |ch, name, received, total| 

    # Calculate percentage complete and format as a two-digit percentage 
    percentage = format('%.2f', received.to_f/total.to_f * 100) + '%' 

    # Print on top of (replace) the same line in the terminal 
    # - Pad with spaces to make sure nothing remains from the previous output 
    # - Add a carriage return without a line feed so the line doesn't move down 
    print "Saving to #{name}: Received #{received} of #{total} bytes" + " (#{percentage})    \r" 

    # Print the output immediately - don't wait until the buffer fills up 
    STDOUT.flush 
end 

puts "Fetch complete!" 
+0

हाँ, यह सबसे अच्छा तरीका है, अच्छी भाषाओं का उपयोग करते समय केवल अपने पुस्तकालयों पर भरोसा करने के लिए तार्किक है। – tokland

संबंधित मुद्दे