Is there way to source csh env file in Ruby?

I want to setup a tool, which set the env by source a csh file.

Is there way to source csh env file in Ruby?

For the attached test case, I wrote ruby as below, but seems don’t work.

#!/usr/bin/env ruby

system “source test.csh”
puts “a = #{ENV[‘SYSTYPE’]}”

Your help will be very appreciated.

Thanks,
Previn

On Tue, Nov 19, 2013 at 5:28 AM, Previn L. [email protected]
wrote:

I want to setup a tool, which set the env by source a csh file.

Is there way to source csh env file in Ruby?

For the attached test case, I wrote ruby as below, but seems don’t work.

#!/usr/bin/env ruby

system “source test.csh”

The shell cannot read a CSV file that way. Even if using the output
in Ruby would work that code breaks already in the shell.

puts “a = #{ENV[‘SYSTYPE’]}”

Your help will be very appreciated.

Use http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html to
iterate records from CSV file and use ENV.[]= to set environment
variables.

Kind regards

robert

Hey Previn,

I think the issue is that the “system” method runs a command in a
subshell, and therefore your program’s executing environment doesn’t
actually ever change

Check out this link for more info:
http://stackoverflow.com/questions/2232/calling-bash-commands-from-ruby

Maybe you could achieve what you are looking for by wrapping it in
another ruby script, ie:

Script 1:
system “source test.csh && ruby script_2.rb”

Script2:
puts “a = #{ENV[‘SYSTYPE’]}”

On Nov 18, 2013, at 11:08 PM, Robert K. [email protected]
wrote:

The shell cannot read a CSV file that way. Even if using the output
in Ruby would work that code breaks already in the shell.

Why CSV? The original poster asked about CSH (Unix C Shell) environment
propagation to Ruby. I think what he wants is this:

csh -c 'source test.csh; env'.lines.each do |_line|
ENV.store *_line.chomp.split(’=’, 2)
end

Then the following will work as expected:
puts “a = #{ENV[‘SYSTYPE’]}”

Michael B. wrote in post #1127833:

Hey Previn,

I think the issue is that the “system” method runs a command in a
subshell, and therefore your program’s executing environment doesn’t
actually ever change

Check out this link for more info:
http://stackoverflow.com/questions/2232/calling-bash-commands-from-ruby

Maybe you could achieve what you are looking for by wrapping it in
another ruby script, ie:

Script 1:
system “source test.csh && ruby script_2.rb”

Script2:
puts “a = #{ENV[‘SYSTYPE’]}”

Hi Michael,

I did as your suggestion, but get error below.

202 %script_1.rb
./test.csh: line 11: syntax error: unexpected end of file

Then I change the test.csh with only one line as below,
209 %cat test.csh
setenv SYSTYPE “Linux”

then run script_1.rb again, it reports

./test.csh: line 1: setenv: command not found

Would you help check and give suggestion?

Many thanks,
Previn

Michael B. wrote in post #1127833:

Hey Previn,

I think the issue is that the “system” method runs a command in a
subshell, and therefore your program’s executing environment doesn’t
actually ever change

Check out this link for more info:
http://stackoverflow.com/questions/2232/calling-bash-commands-from-ruby

Maybe you could achieve what you are looking for by wrapping it in
another ruby script, ie:

Script 1:
system “source test.csh && ruby script_2.rb”

Script2:
puts “a = #{ENV[‘SYSTYPE’]}”

Hi Michael,

With modification as below, it can get right results.

cat script_1.rb
#!/usr/bin/env ruby

system “csh -c ‘source test.csh && script_2.rb’”

But I need process it in one file instead of in “script_2.rb”, in fact,I
need source a cshell file(the test.csh here is just a simple example,
not complete file) to setup env, then start tool accordingly.

So, is there way can source the csh file and still can get the set env
virables in current shell?

Thanks,
Previn

On Nov 18, 2013, at 11:57 PM, Previn L. [email protected] wrote:

Maybe you could achieve what you are looking for by wrapping it in
With modification as below, it can get right results.
So, is there way can source the csh file and still can get the set env
virables in current shell?

%x[ csh -c ‘source test.csh; env’ ].lines.each do |_line|
ENV.store *_line.chomp.split(’=’, 2)
end

Gennady B. wrote in post #1127842:

On Nov 18, 2013, at 11:57 PM, Previn L. [email protected] wrote:

Maybe you could achieve what you are looking for by wrapping it in
With modification as below, it can get right results.
So, is there way can source the csh file and still can get the set env
virables in current shell?

%x[ csh -c ‘source test.csh; env’ ].lines.each do |_line|
ENV.store *_line.chomp.split(’=’, 2)
end

Thanks, Gennady, get all env virables by run shell command env,process
and store with Ruby ENV commands, it works, many thanks.

Gennady B. wrote in post #1127842:

%x[ csh -c ‘source test.csh; env’ ].lines.each do |_line|
ENV.store *_line.chomp.split(’=’, 2)
end

Hi Gennady,

May I ask one more question, how to understand the star(*) in
*_line.chomp.split(’=’, 2)?

On Tue, Nov 19, 2013 at 8:43 AM, Gennady B.
[email protected] wrote:

#!/usr/bin/env ruby

system “source test.csh”

The shell cannot read a CSV file that way. Even if using the output
in Ruby would work that code breaks already in the shell.

Why CSV? The original poster asked about CSH (Unix C Shell) environment
propagation to Ruby.

My bad. This is embarrassing. I am sorry.

Kind regards

robert

Hey Previn,

The asterisk you are asking about takes an array and passes it as
separate args

So for example, some_method( *[x, y] ) is the same as saying
some_method( x, y )

Previn L. wrote in post #1127822:

I want to setup a tool, which set the env by source a csh file.

Is there way to source csh env file in Ruby?

Execute the env file in a csh sript which

  • memorize env before source the file
  • dif the env before/after the source
  • transform the output of diff in a set of ruby affectation

then execute this script by ruby…

exemple (not finish!) :

file cmd_exporter.csh :

set > /tmp/first.data
source $* > /tmp/exec.data
set > /tmp/second.data
cat   /tmp/second.data /tmp/exec.data > /tmp/third.data
diff /tmp/first.data /tmp/third.data | \
  ruby -ne 'puts "%s=%s" % $_.split(/\t/,2)  if $_=~/^> /' | \
  ruby -ne 'puts $_[2..-1].chomp'

=====================================

Env file for test a.csh

set x=22
set y=33
set a=66
echo "Bonjour!"

=====================================

ruby code :
code=csh -c cmd_exporter.csh a.csh
eval code

On Tue, Nov 19, 2013 at 1:08 PM, Robert K.
[email protected] wrote:

For the attached test case, I wrote ruby as below, but seems don’t work.
My bad. This is embarrassing. I am sorry.
I still owe you a proper reply. Here it is:

$ ./test.rb
a = Linux
$ cat test.rb
#!/usr/bin/env ruby

IO.popen([‘csh’, ‘-c’, ‘source test.csh && setenv’]) do |io|
io.each_line do |line|
if %r{^([^=]+)=(.*)$} =~ line
ENV[$1] = $2
else
warn “Cannot read line %p” % line
end
end
end

puts “a = #{ENV[‘SYSTYPE’]}”

The code could be extended in the following ways:

  1. more error checking (e.g. existence of test.csh)
  2. handle variables with values that contain a newline
  3. filter, e.g. include / exclude special variable names or by entries
    already present in the current environment.

The last one is easy, just change one line

ENV[$1] ||= $2

Kind regards

robert

On Nov 19, 2013, at 2:29 AM, Previn L. [email protected] wrote:

*_line.chomp.split(’=’, 2)?
Previn,

Sorry for the delay in replying, did not have an opportunity to review
the list communication. Thanks to Michael B., you got an
explanation earlier :-). Rubys * in front of an array is called splat
operator. For one, it is used to perform in-place array expansion for
method parameters. The following irb session may help in understanding
the concept:

irb(main):001:0> def f(p1, p2)
irb(main):002:1> puts “P1: #{p1.inspect}, P2: #{p2.inspect}”
irb(main):003:1> end
=> nil
irb(main):004:0> a = [ 1, 2 ]
=> [1, 2]
irb(main):005:0> f(a)
ArgumentError: wrong number of arguments (1 for 2)
from (irb):5:in f' from (irb):5 from :0 irb(main):006:0> f(*a) P1: 1, P2: 2 => nil irb(main):007:0> a = [ 1, 2, 3 ] => [1, 2, 3] irb(main):008:0> f(*a) ArgumentError: wrong number of arguments (3 for 2) from (irb):8:inf’
from (irb):8
from :0
irb(main):009:0>

Notice that method f(p1, p2) accepts exactly 2 parameters. So invocation
f(a) fails as it gets only one parameter (array a). However f(*a)
succeeds when array a contains exactly 2 parameters, with a[0] becoming
p1 and a[1] - p2. However, when a has 3 elements, f(*a) fails with
diagnostics that 3 parameters are passed while 2 expected.

More discussions may be found here:
http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator

Hope this helps,
Gennady.

Michael B. wrote in post #1127880:

Hey Previn,

The asterisk you are asking about takes an array and passes it as
separate args

So for example, some_method( *[x, y] ) is the same as saying
some_method( x, y )

Dear Michael,

You’re so nice, I fully understand it now, thanks a lot.

Previn

On Nov 19, 2013, at 4:08 AM, Robert K. [email protected]
wrote:

For the attached test case, I wrote ruby as below, but seems don’t work.
My bad. This is embarrassing. I am sorry.
No problem :-). With so many useful tips and solutions you provide on
this list, you are entitled to an occasional misread ;-). Thanks a lot
for your work.

Gennady.

Gennady B. wrote in post #1128129:

On Nov 19, 2013, at 2:29 AM, Previn L. [email protected] wrote:

More discussions may be found here:
http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator

Hope this helps,
Gennady.

That really helpful, thanks a lot, Gennady.

On Tue, Dec 3, 2013 at 6:48 AM, Previn L. [email protected] wrote:

Thanks for so detailed guide, many thanks.

YWC

By the way, is there something mis-writing? When I run the test.rb you
gave, it reports error below, I’m still checking why?

test.rb:3:in `popen’: can’t convert Array into String (TypeError)

You probably have an old version of Ruby. I tested with 1.9.3

Cheers

robert

Robert K. wrote in post #1129351:

You probably have an old version of Ruby. I tested with 1.9.3

Cheers

robert

Many thanks, Robert, I’ll test it tomorrow with 1.9.3.

Robert K. wrote in post #1128024:

On Tue, Nov 19, 2013 at 1:08 PM, Robert K.
[email protected] wrote:

For the attached test case, I wrote ruby as below, but seems don’t work.
My bad. This is embarrassing. I am sorry.
I still owe you a proper reply. Here it is:

$ ./test.rb
a = Linux
$ cat test.rb
#!/usr/bin/env ruby

IO.popen([‘csh’, ‘-c’, ‘source test.csh && setenv’]) do |io|
io.each_line do |line|
if %r{^([^=]+)=(.*)$} =~ line
ENV[$1] = $2
else
warn “Cannot read line %p” % line
end
end
end

puts “a = #{ENV[‘SYSTYPE’]}”

The code could be extended in the following ways:

  1. more error checking (e.g. existence of test.csh)
  2. handle variables with values that contain a newline
  3. filter, e.g. include / exclude special variable names or by entries
    already present in the current environment.

The last one is easy, just change one line

ENV[$1] ||= $2

Kind regards

robert

Dear Robert,

Thanks for so detailed guide, many thanks.

By the way, is there something mis-writing? When I run the test.rb you
gave, it reports error below, I’m still checking why?

test.rb:3:in `popen’: can’t convert Array into String (TypeError)

Best Regards,
Previn

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs