7

how to pass an environment variable to a shell command that I execute using Kernel#system et al?

say, I want to run

%x{git checkout -f}

but this command relies on the environment variable $GIT_WORK_TREE. how do I set it?

akonsu
  • 28,824
  • 33
  • 119
  • 194

2 Answers2

9

You should be able to set the variable in Ruby's ENV hash prior to calling the sub-shell:

ENV['GIT_WORK_TREE'] = 'foo'
`echo $GIT_WORK_TREE`

should return "foo".

See the ENV[]= documentation for more information.


[1] (pry) main: 0> ENV['GIT_WORK_TREE'] = 'foo'
"foo"
[2] (pry) main: 0> `echo $GIT_WORK_TREE`
"foo\n"
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • This does work, I was about to say the same thing and did a quick check to make sure. – mu is too short Apr 21 '13 at 04:30
  • 1
    As a particular but nasty case, note that your platform could remove some environment variables before launching the sub-shell. For example, [macOS clears DYLD_* env vars when forking](https://apple.stackexchange.com/questions/212945/unable-to-set-dyld-fallback-library-path-in-shell-on-osx-10-11-1). – hmijail Feb 28 '17 at 11:18
1

You can use Process.spawn to set the environment:

spawn({'GIT_WORK_TREE' => '/foo/bar'}, "git checkout -f")
Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
  • thanks. I need to run a few more commands after `git`, can I avoid putting them into a `.sh` file? I was hoping to write a ruby shell script, so to speak. – akonsu Apr 21 '13 at 04:27
  • Ah, from the way you phrased it, I thought you did mean specifically overriding one variable for just one shell command. – Mark Rushakoff Apr 21 '13 at 04:35
  • This also works for `system`, but note that different ways of invoking external commands have different properties / side-effects: https://stackoverflow.com/a/31572431/328817. So `spawn` and `system` are different to each other and also different to backticks. – Sam Aug 01 '22 at 11:42