在Ruby中导出环境变量

时间:2010-04-18 00:08:40

标签: ruby environment-variables

如何将Ruby脚本中的环境变量导出到父shell?例如,实现read Bash内置的朴素实现:

#!/usr/bin/ruby

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

4 个答案:

答案 0 :(得分:36)

简单回答:你不能。

更长的答案:你不能,除非操作环境提供钩子这样做。大多数人没有。您通常可以做的最好的事情是打印出您想要完成的任务,让父母执行它们。

答案 1 :(得分: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[]=确实为在ruby进程中打开的子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 

如果你将它与shell的exec命令结合起来可能会非常有效,它会用ruby进程替换外壳(这样当你退出内壳时,外壳会自动退出好吧,防止任何“我以为我在这个shell中设置该变量”混乱)。

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

答案 2 :(得分:8)

我刚试过这个,看起来不错。

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系统调用一样,允许您指定管道和所有其他东西。

答案 3 :(得分:-1)

ruby​​打印标准导出代码怎么样:

puts "export MYVAR=value"

然后使用shell反引号在shell命令中执行它:

$ `./myscript.rb` 

这将获取脚本的输出并执行它,适用于现代shell,如bash和zsh