在Ruby中导出环境变量

eyh26e7m  于 2023-04-20  发布在  Ruby
关注(0)|答案(4)|浏览(170)

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

#!/usr/bin/ruby

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

lskq00tm1#

你不能将环境变量导出到运行ruby脚本的shell中,但是你可以编写一个ruby脚本来创建一个可源代码的bash文件。
举个例子

% cat 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% cat 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 (这样当你退出内部shell时, shell 也会自动退出,防止任何“我以为我在这个shell中设置了那个变量”的混淆),这将是非常有效的。

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

wvyml7n52#

答案很简单:你不能
更长的答案:你不能,除非操作环境提供了钩子来做这件事。大多数情况下都没有。你通常能做的最好的事情就是打印出你想做的赋值,然后让父级执行它们。

rdlzhqv9

rdlzhqv93#

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

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

niknxzdl

niknxzdl4#

在ruby中打印出标准的导出代码:

puts "export MYVAR=value"

然后使用shell backtick让它在shell命令下执行:

$ `./myscript.rb`

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

相关问题