2011-11-28 27 views
18

tengo que pagar a un proceso al establecer una variable de entorno para ello. He intentado esto de una sola línea:Shell fuera de rubí al establecer una variable de entorno

system "RBENV_VERSION=system ruby extconf.rb" 

Esta sintaxis funciona en el script de shell, pero no de rubí. (Actualización:. resulta esta sintaxis funciona de rubí, después de todo, pero no pudo ver su efecto debido a mi caso de uso particular)

Así que estoy haciendo esto:

rbenv_version = ENV['RBENV_VERSION'] 
ENV['RBENV_VERSION'] = 'system' 
begin 
    system "ruby extconf.rb" 
ensure 
    ENV['RBENV_VERSION'] = rbenv_version 
end 

Me veo forzado a una expresión tan larga porque no quiero anular la variable de entorno de forma permanente si ya tenía un valor.

Algo más corto que viene a la mente?

Respuesta

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

system acepta ningún argumento que Process.spawn acepta.

+1

You da man. \ o/ – mislav

+0

Esta es una gran respuesta. La documentación para ['Kernel # system'] (http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-system) no es suficientemente clara en esta funcionalidad. Muy agradable. – Phrogz

+0

Para ruby ​​1.8, mira POSIX :: Spawn de @ rtomayko, vinculado en otro comentario. – alxndr

2

Esto puede funcionar?

system <<-CMD 
export VARNAME=123 
other_command 
CMD 
+1

que funciona. Una línea: exportar 'system' VARNAME = 123 && other_command'' – mislav

6

Ruby 1.9 incluye Process::spawn que permite que debe proporcionarse un hash Environ.

Process::spawn es también el fundamento de system, exec, popen, etc.
Puede pasar un entorno para cada uno.

Bajo Rubí 1.8, es posible que desee considerar la biblioteca POSIX::Spawn,
que proporciona las mismas interfaces

+0

¡Es bueno saberlo! Pero la invocación es un poco torpe: 'Process.wait Process.spawn ({" MYVAR "=>" 42 "}," echo $ MYVAR ")' para mis necesidades simples. ¡Resulta que el func 'system' también admite este argumento hash opcional! – mislav

+0

'system' acepta todos los argumentos que' Process.spawn() 'acepta. Ver mi respuesta, por ejemplo. – Avdi

3

Usando su mismo enfoque, pero envuelto como un método de bloques que modifica temporalmente el medio ambiente (como la forma de bloque de Dir.chdir):

def with_environment(variables={}) 
    if block_given? 
    old_values = variables.map{ |k,v| [k,ENV[k]] } 
    begin 
     variables.each{ |k,v| ENV[k] = v } 
     result = yield 
    ensure 
     old_values.each{ |k,v| ENV[k] = v } 
    end 
    result 
    else 
    variables.each{ |k,v| ENV[k] = v } 
    end 
end 

with_environment 'RBENV_VERSION'=>'system' do 
    `ruby extconf.rb` 
end 
+0

Uso dicho enfoque a menudo en las pruebas, pero aquí es una exageración. – mislav

+0

@AnonymousDownvoter os animo a downvote respuestas que son _wrong_ y upvote respuestas que son _better_ que otros.Bajar una respuesta (correcta) presumiblemente porque hay otras respuestas que son mejores (más fácil, más corta) no está en el espíritu de Desbordamiento de pila, en mi humilde opinión. – Phrogz

+0

+1 primero, por obtener un voto negativo injusto. Segundo, porque esta es mi respuesta favorita. Estaba más emocionado hasta que me di cuenta de que había definido: with_environment. Es triste, porque ese es el método que debería existir en Ruby. –

3

realidad que trabajó para mí.

[email protected] ~ » irb                                  
1.9.3p0 :001 > system %{SHAIGUITAR=exists ruby -e 'puts ENV["SHAIGUITAR"]'} 
exists 
=> true 

Pero si no lo hace, tal vez pueda probar anteponiendo "env" a cualquier variable que necesite. P.ej.

system(%{env SHAIGUITAR=exists ruby bla.rb}) 
+0

Funciona para mí también. Soy un idiota, lo probé y lo descarté después de que no obtuve el efecto deseado, pero fue por mi caso de uso particular y no porque esto no sea compatible. ¡Gracias! – mislav

+0

Lo único que no funciona con esto, y esto es muy extraño, es el ejemplo de "eco". Es por eso que estoy marcando la otra respuesta como correcta, cubre más casos. – mislav

Cuestiones relacionadas