2011-05-25 10 views
8

मैं जानना चाहता हूं कि मौजूदा टर्मिनल निर्देशिका को बदलना संभव है, जहां से मैं अपनी रूबी स्क्रिप्ट निष्पादित कर रहा हूं।रुबी स्क्रिप्ट से फ़ोल्डर में (टर्मिनल) सीडी कैसे करें

उदाहरण के लिए, यदि मैं टर्मिनल में $HOME से स्क्रिप्ट निष्पादित कर रहा हूं, तो मैं स्क्रिप्ट के अंत में $HOME/mydir में सीडी करना चाहता हूं।

मैंने कुछ चीजों की कोशिश की है, लेकिन मैं हमेशा उसी निर्देशक में खोज रहा हूं जहां लिपि शुरू हुई थी।

बातें मैं कोशिश की है:

Dir.chdir(mydir) 
%[cd mydir] 

वे वास्तव में निर्देशिका बदल सकता है, लेकिन केवल स्क्रिप्ट निष्पादन के सूत्र में। जब स्क्रिप्ट समाप्त होती है, टर्मिनल में मेरा वर्तमान स्थान अभी भी वही है जो मैं स्क्रिप्ट लॉन्च करने से पहले था।

मुझे SO में कुछ समान मिला है, लेकिन यह Python-related है और प्रतिक्रिया नकारात्मक लगती है।


आप पूछ सकते हैं क्यों?

मैं वर्तमान में एक कमांड लाइन एप्लिकेशन (gli का उपयोग कर) में शामिल हूं, जो प्रारंभ बिंदु के रूप में, एक प्रोजेक्ट फ़ोल्डर की आवश्यकता है।

$ myfoo new project 

कौन सा मौजूदा निर्देशिका में नाम project के साथ एक नया फ़ोल्डर बनाता है: तो मेरा पहला आदेश की तरह दिखता है। अब अन्य आदेशों के साथ काम करने के लिए सक्षम होने के लिए मैं की जरूरत है:

$ cd project 
project$ myfoo domore 

तो मैं था बस यह सोच कर कि यह निष्पादित होने myfoo new project के बाद project में मेरी आत्म पाया करने के लिए अच्छा होगा।


जैसा कि मुझे डर था, यह इतना आसान नहीं है (बिल्कुल संभव नहीं है)। तो रूबीजम्स द्वारा जेनरेट की गई मानक फ़ाइल के स्थान पर, एक बाश स्क्रिप्ट का उपयोग करने के बारे में क्या है जो रूबी कॉल करता है? क्या यह व्यवहार्य है? क्या मैं मूर्ख हूँ? क्या मुझे eval का उपयोग करना चाहिए?


उत्तर के लिए धन्यवाद। लेकिन मुझे डर है कि कोई भी स्वीकार्य नहीं है। शायद सवाल नहीं था :)।

+0

ऐसा लगता है कि आप ऐसा करने में सक्षम होंगे। रूबी से कोई भी सिस्टम कॉल आपकी स्क्रिप्ट/खोल से अलग थ्रेड में काम करता है, और इसका वर्तमान स्थान पर कोई प्रभाव नहीं पड़ेगा। आप इसके लिए क्या उपयोग करने की उम्मीद कर रहे हैं? –

+0

@ डगलस-एफ-शीयरर: मैंने जिज्ञासा से बाहर –

+0

उत्तर में मेरे कारणों को थोड़ा बढ़ा दिया है, मेरा जवाब क्यों काम नहीं करता? मैंने इस तकनीक का दो बार उपयोग किया है, और मैं अस्पष्ट हूं कि यह आपकी स्थिति के अनुरूप नहीं है। – Ian

उत्तर

2

यह मेरे ज्ञान के लिए संभव नहीं है, क्योंकि वे अलग-अलग प्रक्रियाएं हैं। यदि आपको रूबी स्क्रिप्ट की मूल प्रक्रिया (बैश) को प्रभावित करने की आवश्यकता है, तो बैश को कुछ स्रोत करने की आवश्यकता होगी। तो आप अपने रूबी स्क्रिप्ट आउटपुट को कुछ बैश कमांड प्राप्त कर सकते हैं, उसके बाद बैश रैपर है जो स्रोत के रूबी का आउटपुट है।

बैश में एक उदाहरण के रूप में इस प्रयास करें,:

`ruby -e 'puts "cd /tmp"'` | source /dev/stdin 

But this will only work in Bash 4.0.

संपादित करें:

असल में, आप इस स्रोत के बजाय eval साथ बैश 3 में कर सकते हैं:

eval $(ruby -e'puts "cd /tmp"') 
+0

ठीक है, लेकिन मैं अपनी स्क्रिप्ट में '% [eval $ (ruby -e'puts" cd/tmp "')]' के साथ समाप्त होता हूं, जो कोई फर्क नहीं पड़ता। –

+0

सही, क्योंकि वहां आप एक बच्चे बैश प्रक्रिया (बैश प्रक्रिया का एक पोती जिसे आप प्रभावित करना चाहते हैं) को जन्म दे रहे हैं, इसमें अपना कोड तैयार कर रहे हैं, और फिर इसे मरने दें। आपको सीधे उस बैश प्रक्रिया में eval चलाने की आवश्यकता है जिसे आप बदलना चाहते हैं। बाद में, आप इसे उपनाम या कुछ के साथ साफ कर सकते हैं। – Ian

+0

मैंने उस उत्तर को बढ़ाया है जो चीज़ को दूसरी तरफ से पूछता है। –

2

मुझे संदेह है कि ऐसा करने का एक सीधा तरीका है।

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

शायद आपकी स्क्रिप्ट बाहर निकलने से पहले नया खोल लॉन्च कर सकती है, तो ऐसा लगता है कि आपके टर्मिनल ने निर्देशिका बदल दी है। हालांकि, आपको अपने टर्मिनल सत्र से बाहर निकलने से पहले उस अतिरिक्त खोल से बाहर निकलना होगा ...

+0

मैंने उस उत्तर को बढ़ाया है जो चीज़ को दूसरी तरफ से पूछता है। –

0

मध्यरात्रि कमांडर एक खोल उपनाम और एक रैपर-स्क्रिप्ट का उपयोग करके ऐसा करता है।

रैपर एमसी (1) द्वारा लिखे गए फ़ाइल की सामग्री द्वारा निर्धारित निर्देशिका में सीडीइंग के लिए है, और उपनाम source रैपर पर उपयोग किया जाता है, जो इसे लॉगिन खोल में निष्पादित करता है, इसके बजाय सब्सक्राइब की जो कि फोर्क किया गया था, स्क्रिप्ट सामान्य रूप से लॉन्च किया गया था।

सब कुछ, यह इसे बाहर निकलने पर वर्तमान कार्यशील निर्देशिका को बदलने देता है।

ऐसा करने के लिए, आपको उपनाम/रैपर कार्यक्षमता को डुप्लिकेट करने की आवश्यकता होगी। http://midnight-commander.org/browser/contrib देखें कि उन्होंने यह कैसे किया।

+0

क्या कोई दस्तावेज है? मैं इसे अपने उपयोग के मामले में कैसे लागू करूं? –

+0

यह मेरे उत्तर के समान ही है। – Ian

1

शायद थोड़ा आसान,

आप इस लक्ष्य को हासिल करने के लिए माणिक के अंदर एक नया बैश खोल बनाने के बारे में Maerics पद के साथ संयोजन में कार्यकारी उपयोग कर सकते हैं।

exec ruby -e "Dir.chdir('mydir'); exec 'bash'" 

exec, बच्चे प्रक्रिया (रूबी) के साथ माता-पिता की प्रक्रिया (शेल) का स्थान ले लेगा इस प्रकार खोल अब मौजूद नहीं है (कोई बाहर निकलने के लिए की जरूरत है)।

नई निर्देशिका में रूबी रूटीन बैश के अंत में (फिर से exec रूबी में) निकाल दिया जाता है और रूबी प्रक्रिया को प्रतिस्थापित किया जाता है।

+0

मैं इसे रूबीजम के साथ कैसे एकीकृत करूं जिसमें इसका अपना आदेश है, जैसा उत्तर में वर्णित है? –

+0

@empo अंत में रूबी स्क्रिप्ट 'exec' bash 'जोड़ें। कमांड लाइन से, 'exec myfoo new project' होने के लिए कॉल को संशोधित करें। हालांकि यह अभी भी घबराहट है :( – diedthreetimes

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