Home > Archive > Ruby > August 2005 > shell command with envvars - howto?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
shell command with envvars - howto?
|
|
| Wybo Dekker 2005-08-30, 7:58 am |
| I want to make a system calling method that returns output, success rate,
and exit status of a system command, like the sys method in the example
program below. My system call fails, however, when I put a definition of an
environment variable in front of the system command.
It works only if I put &&'s between the envvar definition(s) and the
command, as illustrated in the program. But that means that I'll have to
interpret the argument of my method to insert those &&'s.
Is there a better way?
#!/usr/bin/env ruby
# return output, success rate, and exit status of a system command
def sys(command)
[%x{#{command} 2>&1}, $?.success?, $?.exitstatus]
end
def pr(command,output,success,status)
puts "command: #{command}"
puts " output: #{output}"
puts "success: #{success ? 'succeeded' : 'failed'}"
puts " status: #{status}",''
end
command = "echo hello"; pr(command,*sys(command))
command = "xxxx hello"; pr(command,*sys(command))
command = "x=hello echo $x"; pr(command,*sys(command)) # FAILS!
command = "x=hello && echo $x"; pr(command,*sys(command))
Outputs:
command: echo hello
output: hello
success: succeeded
status: 0
command: xxxx hello
output: sh: xxxx: command not found
success: failed
status: 127
command: x=hello echo $x
output:
success: succeeded
status: 0
command: x=hello && echo $x
output: hello
success: succeeded
status: 0
--
Wybo
| |
| Ara.T.Howard 2005-08-30, 7:02 pm |
| On Tue, 30 Aug 2005, Wybo Dekker wrote:
> command = "x=hello echo $x"; pr(command,*sys(command)) # FAILS!
this doesn't even work from the shell:
harp:~ > x=hello echo $x
(newline)
this is because parameter expansion (of $x) occurs __before__ the x=hello is
set for the local environment. you can see this by doing:
harp:~ > x=hello env|egrep ^x=
x=hello
so here the 'x' is looked for __after__ local env vars are set. this is
detailed here:
http://www.gnu.org/software/bash/ma...href.html#SEC48
alternatives:
using session:
harp:~ > cat a.rb
require 'session'
sh = Session::new
sh.execute 'x=hello'
stdout, stderr = sh.execute 'echo $x'
p stdout
p sh.status
harp:~ > ruby a.rb
"hello\n"
0
another way:
def sys cmd, env = {}
merge_env(env){ [ %x[{ #{ cmd } ;} 2>&1], $?.success?, $?.exitstatus ]}
end
def merge_env new_env, &block
push_env(ENV.to_hash.merge(new_env), &block)
end
def push_env new_env, &block
@env_stack ||= []
cur_env = ENV.to_hash
@env_stack << cur_env
set_env new_env
if block
begin
block[new_env]
ensure
pop_env
end
else
cur_env
end
end
def pop_env
@env_stack ||= []
old_env = @env_stack.pop
if old_env
set_env old_env
else
old_env
end
end
def set_env env
ENV.clear
env.each{|k,v| ENV["#{ k }"] = "#{ v }"}
ENV.to_hash
end
use like
sys 'foobar', 'PATH' => './bin', 'LD_LIBRARY_PATH' => './lib'
hth.
-a
--
========================================
=======================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
========================================
=======================================
| |
| Patrick Gundlach 2005-08-30, 7:02 pm |
| Hello Wybo,
I am not sure if this might break anything, but try inserting a ';'
after your assignment:
command = "x=hello ; echo $x"; pr(command,*sys(command))
Patrick
| |
| Wybo Dekker 2005-08-31, 7:00 pm |
| Ara.T.Howard wrote:
> On Tue, 30 Aug 2005, Wybo Dekker wrote:
>
>
>
> this doesn't even work from the shell:
>
> harp:~ > x=hello echo $x
> (newline)
You're quite right - I have been totally and made the wrong test!
Thanks for helping me out. Thanks also for pointing me to session.rb, which
allows me to get output to stdout and stderr separately.
--
Wybo
|
|
|
|
|