Shell out from ruby while setting an environment variable
system({"MYVAR" => "42"}, "echo $MYVAR")
system
accepts any arguments that Process.spawn
accepts.
Ruby: pass environment variable to sudo script?
you need sudo -E
$ irb
>> system({'MYVAR' => "42"}, "sudo wrapper.sh")
=> true
>> system({'MYVAR' => "42"}, "wrapper.sh")
42
=> true
>> system({'MYVAR' => "42"}, "sudo -E wrapper.sh")
42
=> true
>>
Source shell script into environment within a ruby script
The reason this isn't working for you is b/c ruby runs its system
commands in separate shells. So when one system command finishes, the shell that had sourced your file closes, and any environment variables set in that shell are forgotten.
If you don't know the name of the sourced file until runtime, then Roboprog's answer is a good approach. However, if you know the name of the sourced file ahead of time, you can do a quick hack with the hashbang line.
% echo sourcer.rb
#!/usr/bin/env ruby
exec "csh -c 'source #{ARGV[0]} && /usr/bin/env ruby #{ARGV[1]}'"
% echo my-script.rb
#!/usr/bin/env ruby sourcer.rb /path/to/file/I/want/to/source.csh
puts "HAPPYTIMES = #{ENV['HAPPYTIMES']}"
% ./my-script.rb
HAPPYTIMES = True
All of these will only help you use the set enviroment variables in your ruby script, not set them in your shell (since they're forgotten as soon as the ruby process completes). For that, you're stuck with the source
command.
Passing an environment variable to a shell script from Fastlane
Expanding From Within The Immediate Shell
Assuming that sh
, here, is a fastlane command that invokes a shell command with the given argument as script text:
# as a fastlane directive
sh './decrypt.sh "$ENCRYPTION_P12"'
Note that if this were being literally invoked as a command line for /bin/sh
, it would need a -c
argument:
# in other contexts
sh -c './decrypt.sh "$ENCRYPTION_P12"'
Note that this absolutely depends on ENCRYPTION_P12
being an environment variable -- that is, export
ed to the environment by the system by which it was set.
Expanding from Within The Invoked Script
That said, if it is an environment variable, you have a better option: Just use it.
That is, inside decrypt.sh
, you can refer to "$ENCRYPTION_P12"
without needing to set it explicitly, as the shell implicitly imports all environment variables as shell variables -- and they're passed down to child processes without any explicit actions needed.
Things to Avoid: Shell Injection Attacks
Finally, an aside: The dangerous way to do this would have been something like:
# INSECURE: DO NOT DO THIS
sh "./decrypt.sh #{ENV['ENCRYPTION_P12']}"
or
# STILL INSECURE
sh "./decrypt.sh \"#{ENV['ENCRYPTION_P12'}\""
or
# STILL INSECURE
sh "./decrypt.sh '#{ENV['ENCRYPTION_P12'}'"
...thereby substituting the value into your generated string at the Ruby level. This is dangerous, however, as that string is parsed as code -- meaning that contents of ENCRYPTION_P12
could then be leveraged in shell attacks.
For instance, consider the case (given below in bash syntax):
# this will make any of the above do Very Evil Things
ENCRYPTION_P12=$'$(rm -rf ~)\'$(rm -rf ~)\''
...for which both rm
s will execute if directly substituted into generated shell script (as opposed to expanded during parameter expansion -- '${foo}'
-- which takes place after the expansion phases which make this dangerous have already passed).
How do I save changes to the system ENV from Ruby (NOT COMMAND SHELL)?
Unfortunately you cannot have a process directly save an environment setting, however you can check out this:
Persisting an environment variable through Ruby
To see how to take advantage of saving the values in registry and making it eventually make it to the environment variables.
Exporting an Environment Variable in Ruby
Simple answer: You can't.
Longer answer: You can't, unless the operating environment provides hooks to do so. Most do not. The best you can usually do is print out the assignments you want done and have the parent execute them.
Ruby, which exception is best to handle unset environment variables?
Could use ENV.fetch('FOO') which then raises a KeyError if not found.
Related Topics
Gem Install Error (Sass Compass)
How to Uninstall Ruby from /Usr/Local
Using Instance Variables in Class Methods - Ruby
Why Should One Use a Http Server in Front of a Framework Web Server
How to Install the Ruby Ri Documentation
Ruby on Rails - "Add 'Gem SQLite3'' to Your Gemfile"
Is It Possible for Rspec to Expect Change in Two Tables
Irb History Not Working with Ruby 2.3.0
Is There a Natural_Sort_By Method for Ruby
Differencebetween <%= ... %> and <% ... %> in Ruby on Rails
How to Sort a Ruby Hash by Number Value
Create Module Variables in Ruby
Gem Install Pg Doesn't Work on Osx Lion
Where's the Best Place to Define a Constant in a Ruby on Rails Application