2012-02-20 2 views
14

Я использую ruby ​​1.8.7 patch 249. Является ли следующий/лучший способ передать переменные окружения команде оболочки, которую мне нужно выполнить из моей рубиновой программы?Правильный способ передать переменные среды команде exec shell

fork do  
    ENV['A'] = 'A' 
    exec "/bin/bash -c 'echo $A'" 
end 

Process.wait 
+0

То же самое для 'system': http://stackoverflow.com/questions/8301294/shell-out-from-ruby-while-setting-a-environment-variable –

ответ

0

Я хотел бы сделать это в одной строке

exec "/bin/bash -c 'A=hello; echo $A'" 
+1

Мне нравится мой путь лучше, потому что тогда вам не нужно беспокоиться о побегах с запятой, одинарных кавычках и о чем-либо еще, что bash будет интерпретировать в специальном путь. –

11

docs for Ruby's exec method кажется неполным, но это не говорит, что это необязательный первый аргумент называется env, поэтому предположительно, что указует на окружающую среду. С догадкой и Поэкспериментировав, я узнал, что правильный способ использовать это:

exec({"A"=>"A"}, "/bin/bash -c 'echo $A'") 

EDIT 1: К сожалению, не работает для старых версий Ruby.

+2

Я также хотел бы упомянуть, что вам не нужно привлекать 'bash', если вы просто пытаетесь запустить программу и не нуждаетесь в каких-либо причудливых функциях оболочки. Например, 'exec ({}," ls ")' отлично работает и должен быть немного быстрее, потому что мы не запускали bash. –

+0

Отличный ответ, я понял это раньше года или более назад, но все же не понял, что это правильный способ сделать это из документов ([rdoc.info] (http://rdoc.info/stdlib /core/1.9.3/Kernel:exec) docs немного отличаются и делают вид, что вы должны поместить env хэш после программы и ее аргументов). –

+0

@DavidGrayson: Вы уверены, что это работает в 1.8.7? –

3

Для пользователей 1.8 ~ - повторяет 1.9 поведение exec. Однако, как и первоначальная попытка OP.

def exec_env(hash, cmd) 
    hash.each do |key,val| 
    ENV[key] = val 
    end 
    exec cmd 
end 

exec_env({"A"=>"A"}, "/bin/bash -c 'echo $A'") 
+0

Это работает для 'exec', так как' exec' никогда не возвращается, но обратите внимание, что для 'system', который имеет те же сигнатурные переменные окружения, которые установлены с помощью' system (env_hash, command) ', установлены для команды, но не слева в ENV Руби, когда команда завершена. –

23

Существует очень простой способ:

system({"MYVAR" => "42"}, "echo $MYVAR") 

Все это заслуга идет в AVDI: https://stackoverflow.com/a/8301399/171933

+1

Стоит отметить, что 'popen3' имеет такое же поведение с контролем над stdin, stdout, stderr, см. [Https://ruby-doc.org/stdlib-2.4.0/libdoc/open3/rdoc/Open3.html#method -c-popen3] (https://ruby-doc.org/stdlib-2.4.0/libdoc/open3/rdoc/Open3.html#method-c-popen3) –

Смежные вопросы