रूबी, निष्पादन, प्रणाली और% x () या बैकटिक्स के बीच अंतर


370

निम्नलिखित रूबी विधियों में क्या अंतर है?

exec, systemऔर %x()या बैकटिक्स

मुझे पता है कि वे रूबी के माध्यम से प्रोग्रामेटिक रूप से टर्मिनल कमांड निष्पादित करने के लिए उपयोग किए जाते हैं, लेकिन मैं यह जानना चाहूंगा कि ऐसा करने के तीन अलग-अलग तरीके क्यों हैं।


1
: ये आदेश, और कई अन्य लोगों, डॉक्स में बहुत अच्छी तरह से समझाया गया है कार्यकारी प्रणाली बैकटिक
zetetic

1
उस विषय पर एक महान रूबी क्विकटिप्स लेख है: शेल कमांड निष्पादित करें
सिमोन पेरपेलित्सा

6
चूंकि किसी ने इस पुराने धागे को खोदा, "वर्किंग विथ यूनिक्स प्रोसेस" इस विषय में रुचि रखने वाले रूबिस्टों के लिए एक उत्कृष्ट पुस्तक है: workingwithunixprocesses.com
माइकल कोहल

1
मुझे आश्चर्य है कि उत्तर में से कोई भी उल्लेख नहीं है sh
डेनिस

@ डेनिस जब मैं इस सवाल को बढ़ा रहा था 1.9.3 * जारी नहीं किया गया।
श्री काले

जवाबों:


411

प्रणाली

systemविधि एक प्रणाली कार्यक्रम कहता है। आपको इस विधि के लिए एक स्ट्रिंग तर्क के रूप में कमांड प्रदान करना होगा। उदाहरण के लिए:

>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true

लागू कार्यक्रम वर्तमान का उपयोग करेगा STDIN, STDOUTऔर STDERRअपनी रूबी कार्यक्रम की वस्तुओं। वास्तव में, वास्तविक वापसी मूल्य या तो है true, falseया nil। उदाहरण में दिनांक IO ऑब्जेक्ट के माध्यम से मुद्रित किया गया था STDINtrueयदि प्रक्रिया शून्य स्थिति के साथ बाहर निकल जाती है, falseतो प्रक्रिया वापस आ जाएगी यदि गैर-शून्य स्थिति के साथ प्रक्रिया nilसमाप्त हो गई और यदि निष्पादन विफल हो गया।

एक अन्य दुष्प्रभाव यह है कि वैश्विक चर $?एक Process::Statusवस्तु पर सेट है । इस ऑब्जेक्ट में कॉल स्वयं के बारे में जानकारी होगी, जिसमें चालान प्रक्रिया की प्रक्रिया पहचानकर्ता (पीआईडी) और निकास स्थिति शामिल है।

>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>

बैकटिक

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

>> `date`
=> Wed Sep 4 22:22:51 CEST 2013   

वैश्विक चर $?बैकटिक्स के माध्यम से भी सेट किया गया है। बैकटिक्स के साथ आप उपयोग स्ट्रिंग इंटरपोलेशन भी कर सकते हैं।

%एक्स()

का उपयोग करना %xbackticks शैली का एक विकल्प है। यह आउटपुट भी लौटाएगा। अपने रिश्तेदारों %wऔर %q(दूसरों के बीच) की तरह, किसी भी सीमांकक को लंबे समय तक ब्रैकेट-शैली के सीमांकक मैच के रूप में पर्याप्त होगा। इसका मतलब है %x(date), %x{date}और %x-date-सभी पर्यायवाची हैं। बैकटिक्स की तरह%x स्ट्रिंग प्रक्षेप का उपयोग कर सकते हैं।

कार्यकारी

Kernel#execवर्तमान प्रक्रिया का उपयोग करके (आपकी रूबी लिपि) को इस प्रक्रिया से बदल दिया जाता है exec। विधि तर्क के रूप में एक स्ट्रिंग ले सकती है। इस मामले में स्ट्रिंग शेल विस्तार के अधीन होगी। जब एक से अधिक तर्क का उपयोग किया जाता है, तो पहले एक कार्यक्रम को निष्पादित करने के लिए उपयोग किया जाता है और निम्नलिखित को कार्यक्रम के तर्क के रूप में प्रदान किया जाता है।

Open3.popen3

कभी-कभी आवश्यक जानकारी मानक इनपुट या मानक त्रुटि के लिए लिखी जाती है और आपको उन पर भी नियंत्रण पाने की आवश्यकता होती है। यहाँ Open3.popen3काम आता है:

require 'open3'

Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
   pid = thread.pid
   puts stdout.read.chomp
end

3
कैसे कॉल हैंडल की अधिक कुशल नियंत्रण के लिए और STDIN, STDOUT, STDERR, पर विचार Open3.popen3के बजाय; उदाहरण के लिए देखें stackoverflow.com/a/10922097/258662
cboettig

1
यह उल्लेख करने के लिए धन्यवाद कि backticks स्ट्रिंग इंटरपोलेशन का समर्थन करता है जिसने मेरी समस्या को हल किया।
ADG

244

यहाँ इस जवाब पर आधारित एक फ़्लोचार्ट है । यह भी देखें, का उपयोग करते हुए scriptएक टर्मिनल का अनुकरण करने की

यहां छवि विवरण दर्ज करें


3
यह इतना सरल नहीं है। मेरे मामले में यह "ठीक था (और ज़रूरत है) प्रक्रिया को पूरा होने तक अवरुद्ध करने के लिए" फिर STDOUT / STDERR आउटपुट की जाँच करने के लिए popen3 का उपयोग करें।
Nakilon

आप हमेशा इसे (प्रभावी रूप से) ब्लॉक को थोड़ी देर के लूप में लपेटकर गैर-अवरोधक कॉल का कारण बन सकते हैं। आप इतनी आसानी से एक ब्लॉकिंग कॉल को नॉन-ब्लॉकिंग कॉल में नहीं कर सकते।
इयान

106

वे अलग-अलग काम करते हैं। execनई प्रक्रिया के साथ वर्तमान प्रक्रिया को बदलता है और कभी नहीं लौटता हैsystemकिसी अन्य प्रक्रिया को आमंत्रित करता है और वर्तमान प्रक्रिया के लिए इसका निकास मान लौटाता है। बैकटिक्स का उपयोग दूसरी प्रक्रिया को आमंत्रित करता है और उस प्रक्रिया के आउटपुट को वर्तमान प्रक्रिया में लौटाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.