'allo,
Context: I'm replacing parts of an existing collection of shell scripts
and bits of Perl with a unified Ruby system (this despite little to no
understanding of either of the first two...). In one particular case, I
have a script (values.sh) which contains instructions like
VARIABLE=VALUE
The results of which I would really like to be able to see from Ruby.
I'm told that it's setting environment variables and that the values
are visible from the calling script because it invokes values.sh with a
leading period, which causes them to share an environment - fair
enough.
The question is this: if I call values.sh from within Ruby (with a
leading period) will I be able to see the updated environment variables
after it returns, or is this behaviour specific to when one shell
script calls another? (They're ksh scripts, if that information is
helpful)
I'd test this myself, but I have no access to any *NIX boxes until I've
completed the design stage of this project... and my history is sadly
Windowsy. 
Cheers
···
--
Ben
The second one, fortunately or unfortunately as the case may be. . <script> is the source command in ksh, it's equivalent to typing the contents of the shell script in the original file. Theres no why for a child process to affect it's parent's environment. OTOH if values.sh has simple value parts you may be able to parse the script with ruby to pull in the info.
···
On Jul 25, 2006, at 1:25 PM, Ben Zealley wrote:
The question is this: if I call values.sh from within Ruby (with a
leading period) will I be able to see the updated environment variables
after it returns, or is this behaviour specific to when one shell
script calls another? (They're ksh scripts, if that information is
helpful)
i do something like this
require 'session'
bash = Session::Bash.new
stdout, stderr = bash.execute 'ruby -r yaml -e" y ENV "'
before = YAML.load stdout
stdout, stderr = bash.execute '. values.sh'
stdout, stderr = bash.execute 'ruby -r yaml -e" y ENV "'
after = YAML.load stdout
updated = after.to_a - before.to_a
updated.each{|k,v| ENV[k] = v}
which saves you having to parse the file and works even if it's horrifically
complicated...
-a
···
On Wed, 26 Jul 2006, Logan Capaldo wrote:
On Jul 25, 2006, at 1:25 PM, Ben Zealley wrote:
The question is this: if I call values.sh from within Ruby (with a
leading period) will I be able to see the updated environment variables
after it returns, or is this behaviour specific to when one shell
script calls another? (They're ksh scripts, if that information is
helpful)
The second one, fortunately or unfortunately as the case may be. . <script>
is the source command in ksh, it's equivalent to typing the contents of the
shell script in the original file. Theres no why for a child process to
affect it's parent's environment. OTOH if values.sh has simple value parts
you may be able to parse the script with ruby to pull in the info.
--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama
i do something like this
[snip]
Thanks very much - I shall probably use that 
···
--
Ben
"Never worry about theory as long as the machinery does what it's
supposed to do."
- Robert Heinlein
The question is this: if I call values.sh from within Ruby (with a
leading period) will I be able to see the updated environment variables
after it returns, or is this behaviour specific to when one shell
script calls another? (They're ksh scripts, if that information is
helpful)
The second one, fortunately or unfortunately as the case may be. . <script>
is the source command in ksh, it's equivalent to typing the contents of the
shell script in the original file. Theres no why for a child process to
affect it's parent's environment. OTOH if values.sh has simple value parts
you may be able to parse the script with ruby to pull in the info.
i do something like this
require 'session'
bash = Session::Bash.new
stdout, stderr = bash.execute 'ruby -r yaml -e" y ENV "'
before = YAML.load stdout
stdout, stderr = bash.execute '. values.sh'
stdout, stderr = bash.execute 'ruby -r yaml -e" y ENV "'
after = YAML.load stdout
updated = after.to_a - before.to_a
updated.each{|k,v| ENV[k] = v}
which saves you having to parse the file and works even if it's horrifically
complicated...
Very neat hack. Only thing I would change would be to do:
...
after = YAML.load stdout
ENV.update(after)
···
On Jul 25, 2006, at 1:45 PM, ara.t.howard@noaa.gov wrote:
On Wed, 26 Jul 2006, Logan Capaldo wrote:
On Jul 25, 2006, at 1:25 PM, Ben Zealley wrote:
-a
--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama
Erm, *puts on his newbie shirt* I don't seem to have the "session"
package, maybe because this is one-click Ruby for Windows - is it
included by default with the *nix version, or do I need to get it from
somewhere? If the latter, where? I assume
http://rubyforge.org/projects/session is the homepage, but there's
nothing there...
Cheers
···
--
Ben
ara.t.howard@noaa.gov wrote:
On Wed, 26 Jul 2006, Logan Capaldo wrote:
>
> On Jul 25, 2006, at 1:25 PM, Ben Zealley wrote:
>
>> The question is this: if I call values.sh from within Ruby (with a
>> leading period) will I be able to see the updated environment variables
>> after it returns, or is this behaviour specific to when one shell
>> script calls another? (They're ksh scripts, if that information is
>> helpful)
>
> The second one, fortunately or unfortunately as the case may be. . <script>
> is the source command in ksh, it's equivalent to typing the contents of the
> shell script in the original file. Theres no why for a child process to
> affect it's parent's environment. OTOH if values.sh has simple value parts
> you may be able to parse the script with ruby to pull in the info.
i do something like this
require 'session'
bash = Session::Bash.new
stdout, stderr = bash.execute 'ruby -r yaml -e" y ENV "'
before = YAML.load stdout
stdout, stderr = bash.execute '. values.sh'
stdout, stderr = bash.execute 'ruby -r yaml -e" y ENV "'
after = YAML.load stdout
updated = after.to_a - before.to_a
updated.each{|k,v| ENV[k] = v}
which saves you having to parse the file and works even if it's horrifically
complicated...
-a
--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama
it's *nix (or msys or cgywin) specific :
gem install -r session
you don't need session btw. this'll do it too:
harp:~ > cat a.rb
require 'yaml'
require 'tempfile'
def tmpfile txt = ''
t = Tempfile.new rand.to_s
t.write txt
t.close
t.path
end
values_sh = tmpfile %q(
export KEY=VALUE
export date=`date`
export foo=bar
)
def propagate_env path
cmds = <<-cmds
echo __before__; ruby -r yaml -e' y ENV.to_hash '; echo __before__
. #{ path }
echo __after__; ruby -r yaml -e' y ENV.to_hash '; echo __after__
cmds
stdout =
IO.popen('sh', 'w+') do |sh|
sh.write cmds
sh.close_write
sh.read
end
raise "env failure from <#{ path }>" unless $?.exitstatus == 0
before = YAML.load %r/__before__\s*(.*)\s*__before__/mio.match(stdout)[1]
after = YAML.load %r/__after__\s*(.*)\s*__after__/mio.match(stdout)[1]
updated = {}
after.each do |k,v|
updated[k] = v if before[k].nil? or before[k] != after[k]
end
ENV.update updated
updated
end
propagate_env values_sh
p ENV['date']
p ENV['foo']
harp:~ > ruby a.rb
"Tue Jul 25 14:57:06 MDT 2006"
"bar"
regards.
-a
···
On Wed, 26 Jul 2006, Ben Zealley wrote:
Erm, *puts on his newbie shirt* I don't seem to have the "session"
package, maybe because this is one-click Ruby for Windows - is it
included by default with the *nix version, or do I need to get it from
somewhere? If the latter, where? I assume
http://rubyforge.org/projects/session is the homepage, but there's
nothing there...
Cheers
--
Ben
--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama
Well, I've bullied them into giving me access to a box, and got Ruby,
RubyGems and session installed and apparently working - by reference to
about three *nix newbie tutorials, but still, it's working 
In the name of simplicity (my manager is unlikely to be happy with
anything as complex-looking as the second code sample you gave me,
which did work - thankyou!), I'd like to use your original example.
However, I'm getting the following error:
[root@pc2461 ~]# ruby ara.rb
ara.rb:18: warning: default `to_a' will be obsolete
ara.rb:18: warning: default `to_a' will be obsolete
ara.rb:22:in `[]=': can't convert Object into String (TypeError)
from ara.rb:22
from ara.rb:22
I've tried playing around a bit but I can't seem to get much more than
that. Although "updated" ends up as an Array it only contains one value
(which is just of type Object, and doesn't correspond to any obvious
objects like "nil"...). (I've wrapped the "real" .sh I want to capture
variables from - it sets 8) Do you have any guesses as to why that's
happened?
Thanks so much for taking the time to help me with this!
···
--
Ben
"Life is "trying things to see if they work"." - Ray Bradbury