2012-02-20 11 views
14

Używam poprawki ruby ​​1.8.7 249. Czy poniższy najlepszy/jedyny sposób przekazania zmiennych środowiskowych do polecenia powłoki, które muszę wykonać z mojego programu ruby?Prawidłowy sposób przekazywania zmiennych środowiskowych do komendy exec shell

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

Process.wait 
+0

samo dla 'Systemem: http://stackoverflow.com/questions/8301294/shell-out-from-ruby-while-setting-an-environment-variable –

Odpowiedz

0

Chciałbym zrobić to w jednym wierszu

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

Podobają mi się lepiej, bo wtedy nie musisz się martwić o ucieczkę średników, pojedynczych cudzysłowów i wszystkiego, co bash interpretowałaby w specjalnym droga. –

11

docs for Ruby's exec method wydają się niepełne, ale to nie znaczy że jest opcjonalnym pierwszy argument nazywa env, więc przypuszczalnie który określa środowisko. Z zgaduje i niektóre eksperymentowanie, okazało się, że we właściwy sposób z niego korzystać to:

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

EDIT 1: Niestety, nie działa na starszych wersjach Ruby.

+2

Chciałbym również wspomnieć, że nie musisz włączać 'bash', jeśli próbujesz uruchomić program i nie potrzebujesz żadnych specjalnych funkcji powłoki. Na przykład 'exec ({}," ls ")' działa dobrze i powinno być nieco szybsze, ponieważ nie uruchomiliśmy bash. –

+0

Świetna odpowiedź, wymyśliłem to przed rokiem lub więcej temu, a jednak wciąż nie zdawałem sobie sprawy, że to był właściwy sposób na zrobienie tego z dokumentów ([rdoc.info] (http://rdoc.info/stdlib /core/1.9.3/Kernel:exec) dokumenty są trochę inne i sprawiają, że wygląda na to, że powinieneś umieścić skrót ENV po programie i jego argach). –

+0

@DavidGrayson: Czy na pewno działa to w wersji 1.8.7? –

3

Dla użytkowników 1.8 ~ - replikuje zachowanie 1.9 exec. Tak samo jak początkowa próba 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

To działa dla 'exec', ponieważ' exec' nigdy nie zwraca, ale zauważ, że jest inaczej dla 'system', który ma ten sam podpis - zmienne środowiskowe ustawione przez' system (env_hash, command) 'są ustawione dla polecenia, ale nie pozostawione w 'ENV' Rubiego po zakończeniu polecenia. –

23

Jest bardzo prosty sposób:

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

Wszystko kredyt za tym idzie do Avdi: https://stackoverflow.com/a/8301399/171933

+1

Warto zauważyć, że 'popen3' ma takie samo zachowanie przy kontroli nad stdin, stdout, stderr zobacz [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) –

Powiązane problemy