2010-04-18 117 views
36

如何從Ruby腳本中將環境變量導出到父shell?例如,實現一個天真的實施read猛砸內置的:在Ruby中導出環境變量

#!/usr/bin/ruby 

varname = ARGV[0] 
ENV[varname] = STDIN.gets # but have varname exported to the parent process 
+2

我見過[類似的問題](http://stackoverflow.com/questions/190168/persisting-an-environment-variable-through-ruby),但我我不滿意與平臺特定的答案編輯。 – wilhelmtell 2010-04-18 00:09:34

回答

34

答案很簡單:你不能。

較長的答案:除非操作環境提供掛鉤,否則不能。大多數不。你通常能做的最好的事情就是打印你想完成的任務並讓父母執行它們。

+0

看看peterk的答案,它也適用於windows。我試圖用rake的sh執行dos命令,要求在rake中設置env。 – kite 2013-01-27 20:25:55

+5

@kite:作爲一個替代方案,可以考慮在「父shell」 – 2013-01-28 02:47:42

+1

中設置一個憑證dotfile – 2017-02-27 19:22:36

35

您不能將環境變量導出到運行ruby腳本的shell中,但是您可以編寫一個ruby腳本來創建可源代碼的bash文件。

例如

% echo set_var.rb 
#!/usr/bin/env ruby 
varname = ARGV[0] 
puts "#{varname}=#{STDIN.gets.chomp}" 
% set_var.rb FOO 
1 
FOO=1 
% set_var.rb BAR > temp.sh ; . temp.sh 
2 
% echo $BAR 
2 
% 

另一個替代方案是,使用ENV[]=不設置環境變量用於從紅寶石過程內打開子shell。例如:

outer-bash% echo pass_var.rb 
#!/usr/bin/env ruby 
varname = ARGV[0] 
ENV[varname] = STDIN.gets.chomp 
exec '/usr/bin/env bash' 
outer-bash% pass_var.rb BAZ 
quux 
inner-bash% echo $BAZ 
quux 

,如果你與外殼的exec命令,將取代外殼體與紅寶石過程(這樣,當你退出內殼,外殼汽車結合起來這可能是非常有效的也退出,防止任何「我以爲我在這個shell中設置該變量」混淆)。

# open terminal 
% exec pass_var.rb BAZ 
3 
% echo $BAZ 
3 
% exit 
# terminal closes 
7

我剛試過這個,看起來不錯。

cmd = "echo \"FOO is \\\"$FOO\\\"\"";         
system(cmd); 

# Run some Ruby code (same program) in the child process 
fork do 
    puts "In child process. parent pid is #$$" 
    ENV['FOO']='foo in sub process'; 
    system(cmd); 
    exit 99 
end 
child_pid = Process.wait 
puts "Child (pid #{child_pid}) terminated with status #{$?.exitstatus}" 

system(cmd); 

這似乎效果不錯 - 至少在MacOSX上

我得到

FOO is "" 
In child process. parent pid is 1388 
FOO is "foo in sub process" 
Child (pid 1388) terminated with status 99 
FOO is "" 

看上去不錯在它恢復以前的狀態自動

確定 - 現在嘗試一個不同的這不產生2個子過程

Use Process.spawn(env,command) 

pid = Process.spawn({ 'FOO'=>'foo in spawned process'}, cmd); 
pid = Process.wait(); 

這就像C系統調用,並允許你指定管道和所有其他的東西。

0

關於紅寶石打印出標準出口代碼是什麼:

puts "export MYVAR=value" 

,然後用外殼反引號把它的外殼命令對應的執行:

$ `./myscript.rb` 

這需要腳本的輸出和執行它,在現代shell中工作,如bash和zsh

+0

不幸的是,這也不起作用,因爲它仍然不直接在父shell中執行操作。 – Julian 2015-11-09 14:30:40