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

Attachments:
http://www.ruby-forum.com/attachment/8930/testcase.tar.gz

···

--
Posted via http://www.ruby-forum.com/.

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 Class: CSV (Ruby 1.9.3) to
iterate records from CSV file and use ENV.= to set environment
variables.

Kind regards

robert

···

On Tue, Nov 19, 2013 at 5:28 AM, Previn Lin <lists@ruby-forum.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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:

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']}"

···

--
Posted via http://www.ruby-forum.com/.

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 )

···

--
Posted via http://www.ruby-forum.com/.

Previn Lin 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 sourece the file
* dif the env before/after the source
* transform the output if 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

--
Posted via http://www.ruby-forum.com/\.

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.

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']}"

···

On Nov 18, 2013, at 11:08 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Tue, Nov 19, 2013 at 5:28 AM, Previn Lin <lists@ruby-forum.com> wrote:

puts "a = #{ENV['SYSTYPE']}"

Your help will be very appreciated.

Use Class: CSV (Ruby 1.9.3) to
iterate records from CSV file and use ENV.= to set environment
variables.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Michael Bostler 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

···

--
Posted via http://www.ruby-forum.com/\.

Michael Bostler 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

···

--
Posted via http://www.ruby-forum.com/\.

My bad. This is embarrassing. I am sorry.

Kind regards

robert

···

On Tue, Nov 19, 2013 at 8:43 AM, Gennady Bystritsky <gennady-ruby@bystr.com> wrote:

On Nov 18, 2013, at 11:08 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Tue, Nov 19, 2013 at 5:28 AM, Previn Lin <lists@ruby-forum.com> 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.

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

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Michael Bostler 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

···

--
Posted via http://www.ruby-forum.com/\.

Michael Bostler 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:
How to call shell commands from Ruby - Stack Overflow

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?

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

···

On Nov 18, 2013, at 11:57 PM, Previn Lin <lists@ruby-forum.com> wrote:

Thanks,
Previn

--
Posted via http://www.ruby-forum.com/\.

Gennady Bystritsky wrote in post #1127842:

···

On Nov 18, 2013, at 11:57 PM, Previn Lin <lists@ruby-forum.com> 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.

--
Posted via http://www.ruby-forum.com/\.

Gennady Bystritsky 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)?

···

--
Posted via http://www.ruby-forum.com/\.

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 Tue, Nov 19, 2013 at 1:08 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Tue, Nov 19, 2013 at 8:43 AM, Gennady Bystritsky > <gennady-ruby@bystr.com> wrote:

On Nov 18, 2013, at 11:08 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Tue, Nov 19, 2013 at 5:28 AM, Previn Lin <lists@ruby-forum.com> 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.

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

My bad. This is embarrassing. I am sorry.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

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

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.

···

On Nov 19, 2013, at 4:08 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Tue, Nov 19, 2013 at 8:43 AM, Gennady Bystritsky > <gennady-ruby@bystr.com> wrote:

On Nov 18, 2013, at 11:08 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Tue, Nov 19, 2013 at 5:28 AM, Previn Lin <lists@ruby-forum.com> wrote:

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Gennady Bystritsky 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)?

Previn,

Sorry for the delay in replying, did not have an opportunity to review the list communication. Thanks to Michael Bostler, you got an explanation earlier :-). Ruby’s * 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
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:in `f'
        from (irb):8
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:

Hope this helps,
Gennady.

···

On Nov 19, 2013, at 2:29 AM, Previn Lin <lists@ruby-forum.com> wrote:
        from :0
        from :0

--
Posted via http://www.ruby-forum.com/\.

Robert Klemme wrote in post #1128024:

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

···

On Tue, Nov 19, 2013 at 1:08 PM, Robert Klemme > <shortcutter@googlemail.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

Gennady Bystritsky wrote in post #1128129:

···

On Nov 19, 2013, at 2:29 AM, Previn Lin <lists@ruby-forum.com> wrote:
......
More discussions may be found here:
Ruby idioms : The splat operator. | The Plan A

Hope this helps,
Gennady.

That really helpful, thanks a lot, Gennady.

--
Posted via http://www.ruby-forum.com/\.

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

···

On Tue, Dec 3, 2013 at 6:48 AM, Previn Lin <lists@ruby-forum.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme 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.

···

--
Posted via http://www.ruby-forum.com/\.