Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run a command line with custom environment

In Ruby, I want to be able to:

  1. run a command line (via shell)
  2. capture both stdout and stderr (preferably as single stream) without using >2&1 (which fails for some commands here)
  3. run with additional enviornment variables (without modifying the environment of the ruby program itself)

I learned that Open3 allows me to do 1 and 2.

              cmd = 'a_prog --arg ... --arg2 ...'
              Open3.popen3("#{cmd}") { |i,o,e|
                output = o.read()
                error = e.read()
                # FIXME: don't want to *separate out* stderr like this
                repr = "$ #{cmd}\n#{output}"
              }

I also learned that popen allows you to pass an environment but not when specifying the commandline.

How do I write code that does all the three?

...

Put differently, what is the Ruby equivalent of the following Python code?

>>> import os, subprocess
>>> env = os.environ.copy()
>>> env['MYVAR'] = 'a_value'
>>> subprocess.check_output('ls -l /notexist', env=env, stderr=subprocess.STDOUT, shell=True)
like image 612
Sridhar Ratnakumar Avatar asked May 06 '11 22:05

Sridhar Ratnakumar


People also ask

What is command line environment?

Command line environment The environment of the command line refers to the settings and preferences of the current user. It enables users to set greetings, alias commands, variables, and much more.

How do I create an env file in Terminal?

If you have a Unix/Linux/MacOs terminal you navigate to the project root directory and type touch . env which will create a file named . env to hold configuration information.


Video Answer


1 Answers

Open.popen3 optionally accepts a hash as the first argument (in which case your command would be the second argument:

cmd = 'a_prog --arg ... --arg2 ...'
Open3.popen3({"MYVAR" => "a_value"}, "#{cmd}") { |i,o,e|
  output = o.read()
  error = e.read()
  # FIXME: don't want to *separate out* stderr like this
  repr = "$ #{cmd}\n#{output}"
}

Open uses Process.spawn to start the command, so you can look at the documentation for Process.spawn to see all of it's options.

like image 151
Dylan Markow Avatar answered Nov 30 '22 14:11

Dylan Markow