2010-04-18 116 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