2010-01-26 7 views
5

मैं अपने रूबी कार्यक्रम के भीतर से कुछ तीसरे पक्ष की बैश स्क्रिप्ट चलाने की कोशिश कर रहा हूं।रूबी स्क्रिप्ट में कमांड शैल के लिए मैं पर्यावरण चर कैसे स्रोत करूं?

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

मैं इस समस्या को कैसे प्राप्त करूं?

उत्तर

7

यह करें:

$ source whatever.sh 
$ set > variables.txt 

और फिर रूबी में:

File.readlines("variables.txt").each do |line| 
    values = line.split("=") 
    ENV[values[0]] = values[1] 
end 

आपके द्वारा इसे चलाने के बाद, आपका पर्यावरण जाना अच्छा होना चाहिए।

+0

बीमार कोशिश करें। तो क्या इसका मतलब है कि स्क्रिप्ट अपनी युक्त शेल प्रक्रिया के पर्यावरण चर को बदल सकती है और इसलिए किसी और बच्चे की प्रक्रिया को सिस्टम कॉल के माध्यम से विरासत के साथ बनाया गया है? – robodisco

+1

नहीं, लेकिन रूबी स्क्रिप्ट से निष्पादित कोई भी प्रक्रिया स्क्रिप्ट के चर का वारिस करेगी। – Geo

+0

उपरोक्त एक धागे के लिए काम करता है और मैं नीचे करता हूं। लेकिन मेरे पास एक सवाल है कि मैं आईओ.पोपेन के साथ पर्यावरण की विलय वाली कॉप का उपयोग कैसे करूं? किसी भी तरह यह काम नहीं लग रहा है। "सिस्टम" के साथ मैं कर सकता हूं: # ... नया "पथ" बनाएं subEnv = हैश.न्यू; subEnv.merge! (ENV); # पुराने वातावरण की प्रतिलिपि subEnv ['पथ'] = पथ; प्रतिलिपि सिस्टम (subEnv, कमांडलाइन) में नए मान सेट करें; – peterk

2

मुझे यकीन नहीं है कि मैं आपके प्रश्न को सही तरीके से समझता हूं। क्या आप किसी अन्य को चलाने से पहले एक शेल स्क्रिप्ट स्रोत करने का प्रयास करते हैं? इस मामले में जवाब सरल है: स्रोत फ़ाइल चर जो अपने आदेश का उपयोग करना चाहिए आप उन्हें export करने के लिए है शामिल

#!/bin/env ruby 
system "source <path_to_source_file> && <command>" 

हैं। ENV['<name_of_var>'] = <value> का उपयोग करके अपनी रूबी स्क्रिप्ट के भीतर पर्यावरण चर सेट करना भी संभव है।


अद्यतन: 26 जनवरी, 2010 - 15:10

आप एक नया खोल खोलने के लिए IO.popen उपयोग कर सकते हैं:

IO.popen("/bin/bash", "w") do |shell| 
    shell.puts "source <path_to_source_file>" 
    shell.puts "<command>" 
end 
+0

मुझे लगता है कि नहीं है कि सिस्टम के साथ निष्पादित करने में मदद करेगा, क्योंकि वार्स केवल खोल प्रक्रिया है कि कि आदेश पर अमल करने पैदा हो जाता है के लिए स्थापित किया जाएगा। – Geo

+0

मैं अपने उपयोगकर्ता निर्देशिका में काम करने के लिए सिस्टम "स्रोत .bashrc" भी प्राप्त नहीं कर सकता। यह शिकायत शिकायत नहीं मिली है। क्या आप सुनिश्चित हैं कि आपके द्वारा पोस्ट किए गए स्रोत का उपयोग किया जा सकता है? – robodisco

+0

यह मेरे लिए काम किया। मैंने ओएसएक्स 10.6 पर यह कोशिश की। क्या उपयोगकर्ता का खोल है जो स्क्रिप्ट को/bin/bash पर सेट करता है? (मैंने अपना उत्तर भी अपडेट किया।) – t6d

0

मैं ऐसा किया क्योंकि मैं एक फ़ाइल में लिखने या इस सामग्री के साथ अपने गहरे लाल रंग का कोड अप मिश्रण करने के लिए नहीं करना चाहता था:

#!/usr/bin/env bash 
eval $(echo "$(cat .env) $1" | tr '\n' ' ') 

मैं के लिए ~/bin/run_with_env.sh में यह रखा और फिर उदाहरण मैं चला सकते हैं:

% run_with_env.sh "rails console" 
2

यह भयानक है, लेकिन ..

env = %x{. /some/shell/script/which/setups/your/env && env} 
env.split("\n").each do |line| 
    key, value = line.split("=", 2) 
    ENV[key] ||= value unless value.nil? or value.empty? 
end 
0

संशोधित करना ENV किसी एकल थ्रेड के लिए ही काम करता है और मैं बेल करना इसके बजाए ओउ लेकिन मेरे पास एक सवाल है कि मैं आईओ.पोपेन के साथ पर्यावरण की विलय वाली कॉप का उपयोग कैसे करूं? किसी भी तरह यह काम नहीं लग रहा है।

"प्रणाली" के साथ

मैं कर सकते हैं:

# ... create new "path" here 

    subEnv = Hash.new; 
    subEnv.merge!(ENV); # copy old environment 
    subEnv['PATH'] = path; # set new values in copy 

    system(subEnv, commandLine);