Как изменить исходные переменные среды для командной оболочки в Ruby script?
Я пытаюсь запустить некоторые сторонние скрипты bash из моей рубиновой программы.
Прежде чем я смогу запустить их, они потребуют от меня файла. В командной строке все работает нормально, но внутри Ruby это не работает. Я узнал, что системные команды откроют новый процесс дочерней оболочки, и любой источник будет выполнен в этом и не будет видно из процесса родительской оболочки, запускающего Ruby script. Когда системный вызов завершается, дочерняя оболочка также убивается.
Как обойти эту проблему?
Ответы
Ответ 1
Сделайте это:
$ source whatever.sh
$ set > variables.txt
И затем в Ruby:
File.readlines("variables.txt").each do |line|
values = line.split("=")
ENV[values[0]] = values[1]
end
После того, как вы запустили это, ваша среда должна быть хорошей.
Ответ 2
Я не уверен, правильно ли понимаю ваш вопрос. Вы пытаетесь запустить оболочку script перед запуском другого? В этом случае ответ прост:
#!/bin/env ruby
system "source <path_to_source_file> && <command>"
Если исходный файл содержит переменные, которые ваша команда должна использовать, вы должны иметь export
их. Также возможно установить переменные среды в Ruby script с помощью 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
Ответ 3
Это ужасно, но..
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
Ответ 4
Я сделал это, потому что я не хотел писать файл или смешивать свой рубиновый код с этим материалом:
#!/usr/bin/env bash
eval $(echo "$(cat .env) $1" | tr '\n' ' ')
Я помещаю это в ~/bin/run_with_env.sh, а затем, например, могу запустить:
% run_with_env.sh "rails console"
Ответ 5
Изменение ENV работает только для одного потока, и я делаю ниже.
Но у меня есть вопрос, как использовать объединенную копию среды с IO.popen? как-то это не работает.
с помощью "системы" я могу сделать:
# ... create new "path" here
subEnv = Hash.new;
subEnv.merge!(ENV); # copy old environment
subEnv['PATH'] = path; # set new values in copy
system(subEnv, commandLine);