2011-11-28 18 views
18

Muszę wykonać polecenie procesu, ustawiając dla niego zmienną środowiskową. Próbowałem ten jeden-liner:Wyłuskanie z ruby ​​podczas ustawiania zmiennej środowiskowej

system "RBENV_VERSION=system ruby extconf.rb" 

składnia działa to w skrypcie, ale nie z rubinem. (Aktualizacja:. okazuje składnia ta współpracuje z ruby ​​po wszystkim, ale nie udało mi się zobaczyć jego działanie ze względu na mój szczególności przypadków użycia)

Więc robię to:

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

Jestem zmuszony do tak długiego wyrażenia, ponieważ nie chcę przesłonić zmiennej środowiskowej na stałe, jeśli ma już wartość.

Coś krótszego, co przychodzi ci na myśl?

Odpowiedz

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

system akceptuje wszystkie argumenty Process.spawn akceptuje.

+1

Ty da man. \ o/ – mislav

+0

To jest świetna odpowiedź. Dokumentacja dla ['Kernel # system'] (http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-system) nie jest wystarczająco jasna na temat tej funkcjonalności. Bardzo dobrze. – Phrogz

+0

Dla ruby ​​1.8, spójrz na POSIX :: Spawn @ rtomayko, połączony w innym komentarzu. – alxndr

2

To może działać?

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

To działa. Jedna linia: eksport "system" VARNAME = 123 && other_command'' – mislav

6

Ruby 1.9 zawiera Process::spawn, co pozwala na zapewnienie wartości mieszania środowiskowego.

Process::spawn jest również podstawą do system, exec, popen itp
można przejść do każdego środowiska.

Zgodnie z Ruby 1.8, może warto rozważyć bibliotekę POSIX::Spawn,
który zapewnia te same interfejsy

+0

Dobrze wiedzieć! Ale inwokacja jest trochę nieprzydatna: 'Process.wait Process.spawn ({" MYVAR "=>" 42 "}," echo $ MYVAR ")' dla moich prostych potrzeb. Okazuje się, że funkcja 'system' również obsługuje ten opcjonalny argument mieszania! – mislav

+0

'system' akceptuje wszystkie argumenty, które akceptuje' Process.spawn() '. Zobacz moją odpowiedź na przykład. – Avdi

3

Używanie samo podejście, ale opakowane jako metoda bloku, który tymczasowo modyfikuje środowisko (jak blokach z 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

Często stosuję takie podejście w testach, ale tutaj jest to przesada. – mislav

+0

@AnonymousDownvoter Zachęcam do odrzucenia odpowiedzi, które są błędne, i przekaż odpowiedzi, które są lepsze od innych.Odstąpienie jednej (poprawnej) odpowiedzi prawdopodobnie dlatego, że istnieją inne odpowiedzi, które są lepsze (łatwiejsze, krótsze) nie jest zgodne z duchem przepełnienia stosu, IMHO. – Phrogz

+0

+1 po pierwsze, za uzyskanie niesprawiedliwego wyniku. 2, ponieważ jest to moja ulubiona odpowiedź. Byłem bardziej podekscytowany, dopóki nie zrozumiałem, że zdefiniowałeś: with_environment. To smutne, ponieważ taka metoda powinna istnieć w samej Ruby. –

3

Właściwie to działało dla mnie.

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

Ale jeśli nie, może możesz spróbować poprzedzić "env" dowolną zmienną, której potrzebujesz. Na przykład.

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

To też działa dla mnie. Jestem idiotą, próbowałem go i wyrzuciłem, gdy nie uzyskałem pożądanego efektu, ale było to spowodowane moim szczególnym przypadkiem użycia, a nie dlatego, że nie jest to obsługiwane. Dzięki! – mislav

+0

Jedyne, co nie działa z tym - a to jest bardzo dziwne - to przykład "echa". Dlatego właśnie zaznaczam drugą odpowiedź jako poprawną - obejmuje ona więcej przypadków. – mislav

Powiązane problemy