Processes Have an Environment
Environment, in this sense, refers to what’s known as ‘environment variables’. Environment variables are key-value pairs that hold data for a process.
Every process inherits environment variables from its parent. They are set by a parent process and inherited by its child processes. Environment variables are per-process and are global to each process.
Here’s a simple example of setting an environment variable in a bash
shell, launching a Ruby process, and reading that environment variable.
$ MESSAGE='wing it' ruby -e "puts ENV['MESSAGE']"
The VAR=value
syntax is the bash
way of setting environment variables. The same thing can be accomplished in Ruby using the ENV
constant.
# The same thing, with places reversed!
ENV['MESSAGE'] = 'wing it'
system "echo $MESSAGE"
Both of these examples print:
wing it
In bash
environment variables are accessed using the syntax: $VAR
. As you can tell from these few examples environment variables can be used to share state between processes running different languages, bash
and ruby
in this case.
It’s a hash, right?
Although ENV
uses the hash-style accessor API it’s not actually a Hash
. For instance, it implements Enumerable
and some of the Hash
API, but not all of it. Key methods like merge
are not implemented. So you can do things like ENV.has_key?
, but don’t count on all hash operations working.
puts ENV['EDITOR']
puts ENV.has_key?('PATH')
puts ENV.is_a?(Hash)
outputs:
vim
true
false
In the Real World
In the real world environment variables have many uses. Here’s a few that are common workflows in the Ruby community:
$ RAILS_ENV=production rails server
$ EDITOR=mate bundle open actionpack
$ QUEUE=default rake resque:work
Environment variables are often used as a generic way to accept input into a command-line program. Any terminal (on Unix or Windows) already supports them and most programmers are familiar with them. Using environment variables is often less overhead than explicitly parsing command line options.
System Calls
There are no system calls for directly manipulating environment variables, but the C library functions setenv(3) and getenv(3) do the brunt of the work. Also have a look at environ(7) for an overview.