tags:

views:

235

answers:

2

I'm trying to run some third party bash scripts from within my ruby program. Before I can run them though they require me to source a file. On the command line it all works fine but within ruby it doesn't work. Ive found out that system commands will open a new child shell process and any sourcing will be done in that and cant be seen from the parent shell process running the ruby script. When the system call ends the child shell is also killed.

So i'm wondering how do i get round this problem?

+2  A: 

I'm not sure if I understand your question correctly. Do you try to source a shell script before running another one? In this case the answer is simple:

#!/bin/env ruby
system "source <path_to_source_file> && <command>"

If the source file contains variables which your command should use you have to export them. It is also possible to set environment variables within your Ruby script by using ENV['<name_of_var>'] = <value>.


Update: Jan 26, 2010 - 15:10

You can use IO.popen to open a new shell:

IO.popen("/bin/bash", "w") do |shell|
  shell.puts "source <path_to_source_file>"
  shell.puts "<command>"
end
t6d
I don't think that Executing with system will help, because the vars will be set only for the shell process that gets spawned to execute that command.
Geo
i cant even get system "source .bashrc" to work in my user directory. It complains command not found. Are you sure source can be used like you posted?
adam
It worked for me. I tried this on OSX 10.6. Is shell of the user who executes the script set to /bin/bash?(I also updated my answer.)
t6d
thanks for your reply. Ive been googling this and cant figure out why i cant source .bashrc inside the script. how do i check if the shell is set to /bin/bash?
adam
The shell varibale $SHELL stores the login shell of the user. I think this should work in this particular case. But remember it's the users login shell, so running something like /bin/sh -c "echo $SHELL" from a bash shell still prints /bin/bash.
t6d
To determine the current shell use the environment variable $0.
t6d
What's the point of executing this? The modified environment won't be reflected in the `ENV` object.
Geo
+1  A: 

Do this:

$ source whatever.sh
$ set > variables.txt

And then in Ruby:

File.readlines("variables.txt").each do |line|
  values = line.split("=")
  ENV[values[0]] = values[1]
end

After you've ran this, your environment should be good to go.

Geo
Ill try this. So does this means the script can alter the enviroment variables of its containing shell process and therefore any further child processes created via system calls with inherit?
adam
No, but any process executed from the Ruby script will inherit the script's variables.
Geo