views:

262

answers:

2

How do I export an environment variable from within a Ruby script to the parent shell? For example, implementing a naïve implementation of the read Bash builtin:

#!/usr/bin/ruby

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

Simple answer: You can't.

Longer answer: You can't, unless the operating environment provides hooks to do so. Most do not. The best you can usually do is print out the assignments you want done and have the parent execute them.

Ignacio Vazquez-Abrams
+3  A: 

You can't export environment variables to the shell the ruby script runs in, but you could write a ruby script that creates a source-able bash file.

For example

% 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
%

Another alternative is that using ENV[]= does set environment variables for subshells opened from within the ruby process. For example:

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 

This can be quite potent if you combine it with the shell's exec command, which will replace the outer-shell with the ruby process (so that when you exit the inner shell, the outer shell auto-exits as well, preventing any "I thought I set that variable in this shell" confusion).

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