如何将Ruby脚本中的环境变量导出到父shell?例如,实现read
Bash内置的朴素实现:
#!/usr/bin/ruby
varname = ARGV[0]
ENV[varname] = STDIN.gets # but have varname exported to the parent process
答案 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