रूबी स्क्रिप्ट के भीतर कमांड लाइन चल रही है


92

क्या रूबी के माध्यम से कमांड लाइन कमांड चलाने का एक तरीका है? मैं एक छोटा सा रूबी प्रोग्राम बनाने की कोशिश कर रहा हूं, जो कमांड लाइन प्रोग्राम जैसे 'स्क्रीन', 'रेज्ज़, आदि' के माध्यम से डायल और रिसीव / सेंड करेगा।

यह बहुत अच्छा होगा अगर मैं यह सब रूबी (MySQL बैकएंड, आदि) के साथ कर सकता हूं।


जवाबों:


209

हाँ। कई तरीके हैं:


ए। उपयोग करें %xया '`':

%x(echo hi) #=> "hi\n"
%x(echo hi >&2) #=> "" (prints 'hi' to stderr)

`echo hi` #=> "hi\n"
`echo hi >&2` #=> "" (prints 'hi' to stderr)

ये विधियाँ स्टडआउट लौटाएगी, और प्रोग्राम के लिए स्ट्रीडर पुनर्निर्देशित करेगी।


ख। उपयोग करें system:

system 'echo hi' #=> true (prints 'hi')
system 'echo hi >&2' #=> true (prints 'hi' to stderr)
system 'exit 1' #=> nil

trueयदि यह आदेश सफल था, तो यह विधि वापस आती है । यह प्रोग्राम के सभी आउटपुट को रीडायरेक्ट करता है।


सी। उपयोग करें exec:

fork { exec 'sleep 60' } # you see a new process in top, "sleep", but no extra ruby process. 
exec 'echo hi' # prints 'hi'
# the code will never get here.

यह वर्तमान प्रक्रिया को कमांड द्वारा बनाई गई एक के साथ बदल देता है।


घ। (रूबी 1.9) का उपयोग करें spawn:

spawn 'sleep 1; echo one' #=> 430
spawn 'echo two' #=> 431
sleep 2
# This program will print "two\none".

यह विधि पीआईडी ​​से बाहर निकलने और वापस आने की प्रक्रिया का इंतजार नहीं करती है।


इ। उपयोग करें IO.popen:

io = IO.popen 'cat', 'r+'
$stdout = io
puts 'hi'
$stdout = IO.new 0
p io.read(1)
io.close
# prints '"h"'.

यह विधि एक ऐसी IOवस्तु लौटाएगी जो नई प्रक्रियाओं के इनपुट / आउटपुट को रिप्रेजेंट करती है। यह वर्तमान में भी एकमात्र तरीका है जो मुझे प्रोग्राम इनपुट देने के लिए पता है।


च। उपयोग Open3(1.9.2 और बाद में)

require 'open3'

stdout,stderr,status = Open3.capture3(some_command)
STDERR.puts stderr
if status.successful?
  puts stdout
else
  STDERR.puts "OH NO!"
end

Open3दो आउटपुट स्ट्रीम में स्पष्ट पहुँच पाने के लिए कई अन्य कार्य हैं। यह पोपेन के समान है, लेकिन आपको stderr तक पहुंच प्रदान करता है।


बोनस चाल io = IO.popen 'cat > out.log', 'r+':; कमांड के आउटपुट को "out.log" पर लिखता है
Narfanator

1
प्रत्येक के लिए प्रो और विपक्ष क्या हैं। मैं कैसे तय करूं कि किसका उपयोग करना है? FileUtils[ Ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html] का उपयोग कैसे करें ?
अवा

1
मैं एक एसवीएन कमांड निष्पादित कर रहा हूं। मैं नहीं चाहता कि निष्पादन का आउटपुट कंसोल पर दिखाई दे। मैं इसे पुनर्निर्देशित करना चाहता हूं ताकि मैं इसे एक चर के रूप में संग्रहीत कर सकूं और इस पर कुछ प्रसंस्करण कर सकूं। मैं यह कैसे करुं ?
स्टैक 1

2
status.successful? अब माणिक 2.4 पर मेरे लिए काम नहीं कर रहा है, यह स्थिति में बदल गया है। असफल? :)
डेनियल

14

रूबी में सिस्टम कमांड चलाने के कुछ तरीके हैं।

irb(main):003:0> `date /t` # surround with backticks
=> "Thu 07/01/2010 \n"
irb(main):004:0> system("date /t") # system command (returns true/false)
Thu 07/01/2010
=> true
irb(main):005:0> %x{date /t} # %x{} wrapper
=> "Thu 07/01/2010 \n"

लेकिन अगर आपको वास्तव में कमांड के स्टड / स्टडआउट के साथ इनपुट और आउटपुट करने की आवश्यकता है, तो आप संभवतः उस IO::popenविधि को देखना चाहेंगे , जो विशेष रूप से उस सुविधा को प्रदान करती है।


अगर आपके ऐप में सिर्फ स्टैंडर्ड आउट है तो पोप अच्छा काम करता है। यदि आपको अधिक सहभागिता की आवश्यकता है या आप stdout, stdin, और विशेष रूप से stderr के साथ कुछ अलग करना चाहते हैं, तो आप भी ओपन 3 में देखना चाहेंगे: ruby-doc.org/core/classes/Open3.html
पॉल रूबेल


2

हां यह निश्चित रूप से उल्लेखनीय है लेकिन कार्यान्वयन की विधि इस बात पर निर्भर करती है कि क्या "कमांड लाइन" प्रोग्राम प्रश्न में "फुल स्क्रीन" या कमांड लाइन मोड में काम करता है। कमांड लाइन के लिए लिखे गए प्रोग्राम STDIN को पढ़ते हैं और STDOUT को लिखते हैं। इन्हें रूबी के भीतर मानक बैकटिक्स विधियों और / या प्रणाली / निष्पादन कॉल का उपयोग करके सीधे बुलाया जा सकता है।

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

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


एक्सपेक्ट का एक सरल संस्करण रूबी में अपने बिल्ट-इन Pty मॉड्यूल का उपयोग करके उपलब्ध है ।
टीन मैन

0

सबसे अधिक उपयोग की जाने वाली विधि Open3यहाँ उपयोग कर रही है, कुछ सुधारों के साथ उपरोक्त कोड का मेरा कोड संपादित संस्करण है:

require 'open3'
puts"Enter the command for execution"
some_command=gets
stdout,stderr,status = Open3.capture3(some_command)
STDERR.puts stderr
if status.success?
  puts stdout
else
  STDERR.puts "ERRRR"
end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.