2012-02-20 10 views
14

Estoy usando ruby ​​1.8.7 patch 249. ¿Es la siguiente/mejor manera de pasar variables de entorno a un comando de shell que necesito ejecutar desde mi programa ruby?Manera correcta de pasar variables de entorno al comando de shell exec

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

Process.wait 
+0

Lo mismo para 'system': http://stackoverflow.com/questions/8301294/shell-out-from-ruby-while-setting-an-environment-variable –

Respuesta

0

lo haría en una línea

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

Me gusta mi camino mejor porque entonces no tiene que preocuparse por escapar de los puntos y comas, comillas simples, y cualquier otra cosa que bash interprete en un especial camino. –

11

El docs for Ruby's exec method parece incompleta, pero sí dice que hay un primer argumento opcional llamado env, por lo que presumiblemente que especifica el medio ambiente. Con una conjetura y algunos experimentos, descubrí que la manera correcta de utilizar es la siguiente:

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

EDIT 1: Lo sentimos, no funciona para versiones anteriores de Ruby.

+2

También me gustaría mencionar que no necesita involucrarse 'bash' si solo está tratando de ejecutar un programa y no necesita funciones especiales de shell. Por ejemplo, 'exec ({}," ls ")' funciona bien y debería ser un poco más rápido porque no iniciamos bash. –

+0

Gran respuesta, ya lo descubrí hace un año o más, y aún así no me di cuenta de que esta era la forma correcta de hacerlo desde los documentos ([rdoc.info] (http://rdoc.info/stdlib) /core/1.9.3/Kernel:exec) docs son un poco diferentes y hacen que parezca que se supone que debes colocar hash de env después del programa y sus argumentos). –

+0

@DavidGrayson: ¿Estás seguro de que esto funciona en 1.8.7? –

3

Para usuarios de 1.8 ~ - replica el comportamiento 1.9 del ejecutor. Igual que el intento inicial de OP sin embargo.

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

Esto funciona para 'exec' ya que' exec' nunca regresa, pero tenga en cuenta que es diferente para 'system', que tiene la misma firma: las variables de entorno establecidas a través de' system (env_hash, command) 'se establecen para el comando, pero no dejado en 'ENV' de Ruby cuando el comando finaliza. –

23

Hay una manera muy fácil:

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

Todo el crédito para esto va a Avdi: https://stackoverflow.com/a/8301399/171933

+1

Vale la pena señalar que 'popen3' tiene el mismo comportamiento con control sobre stdin, stdout, stderr, consulte [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) –

Cuestiones relacionadas