Perl: How to access shell environment variables through Perl associative arrays

Perl shell environment variables FAQ: How can I access Unix shell environment variables from a Perl script?

One of the great features of the Perl language is it's support of associative arrays. Unlike normal arrays, whose subscripts can only be integers, the subscripts of associative arrays are text strings. This may not sound like much yet, but with associative arrays (or hashes as they're now called) we can create fairly complex data structures with Perl.

Perl programs use a special associative array name %ENV to store the shell environment variables they inherit when they begin running. This article explores the proper way to access your shell variables from within a Perl program using the %ENV associative arrays.

Editor's Notes: This article was originally written using Perl in a Sun/Solaris environment, and has not been tested on other operating systems at this time. Some of the environment variables, such as the LOGNAME variable shown next, may not be available on other Unix or non-Unix systems. Also, the term "associative array" was changed to "hash" in the change from Perl 4 to Perl 5. Most people now prefer to call these data types hashes, but our writer doesn't like that term, so in this article, they're still associative arrays.

Accessing shell environment variables in Perl - A simple "Hello" program

It has become stylish when introducing a language to a new audience to begin with a "Hello, world" program. Our approach to this normal introduction will be a bit more personal:

#!/usr/bin/perl 
$userName =  $ENV{'LOGNAME'}; 
print "Hello, $userName\n"; 

This simple program prints a customized "Hello" message when run from the Solaris command line, printing the word "Hello", followed by the users login name. If your login name is fred, and you ran the program shown in Listing 1 from the Solaris command line, the last line of the program would print the following output:

Hello, fred

In this brief program, Perl obtains your username from the special associative array named %ENV. Associative arrays are basically the same as the "normal" arrays you may be used to with other languages, such as C, with one exception. Associative arrays let you use any combination of characters as your array subscripts - you're not limited to simple integers.

The Perl %ENV environment variable array (hash)

The variable ENV is actually a special associative array within Perl that holds the contents of your shell environment variables. You can access any shell environment variable in the same way we accessed the username in Listing 1. For instance, the following commands retrieve the desired PATH and PWD information from a user's environment:

$path = $ENV{'PATH'}; 
$pwd  = $ENV{'PWD'};

As a final introductory note regarding associative arrays, notice that the array subscript is enclosed in curly braces. Normal integer-based arrays in Perl are enclosed in square brackets, such as:

$current_item = $item_array[100];

It's said that associative arrays use fancier brackets than normal arrays because associative arrays are fancier than normal arrays. While I don't know if this statement is 100% accurate, I do find it to be an effective way of remembering the proper subscripting syntax when using Perl arrays.

Printing all of your environment variables in Perl

If you're interested in seeing the contents of all of your environment variables, you can easily print them all out with a foreach command:

foreach (sort keys %ENV) { 
  print "$_  =  $ENV{$_}\n"; 
}

This example illustrates a fairly common occurrence with associative arrays - how to process each element of an associative array.

The keys function gets all of the keys, or subscripts, out of the specified associative array. In this example, the keys of the associative array %ENV will be the name of your environment variables. In Listing 1, the key (or subscript) was 'LOGNAME', and the value of the array element $ENV{'LOGNAME'} was fred:

$ENV{'LOGNAME'} = "fred";

A listing of a few of the keys of the special associative array %ENV are shown in Listing 2.

PERL STATEMENT                    Key          Value 
-------------------------------   ----------   -------------- 
$ENV{'LOGNAME'} = "fred";         LOGNAME      fred 
$ENV{'HOME'}    = "/home/fred";   HOME         /home/fred 
$ENV{'SHELL'}   = "/bin/ksh";     SHELL        /bin/ksh 
$ENV{'EDITOR'}  = "vi";           EDITOR       vi 

Listing 2: This listing shows typical values of several environment variables that would be stored in the associative array %ENV on a Solaris 2.4 system.

When the keys function is run within the foreach loop, it returns only the subscript names LOGNAME, HOME, SHELL, and EDITOR - it does not return the values of each element.

The sort function, which precedes the keys function, sorts the output of the keys command before that output is used by the foreach statement. Given the keys shown in Listing 2, the sorted output would leave the keys in the following order: EDITOR, HOME, LOGNAME, and SHELL.

The foreach statement creates a loop that can be read like this:

"For each element in the list 'EDITOR, HOME, LOGNAME, and SHELL', do everything enclosed in the following curly braces."

This results in the print statement being run for each key in the %ENV environment variables array.

The $_ variable contains the default pattern space when working with Perl.

Therefore, within the foreach loop, the variable $_ will be assigned the contents of the list of sorted keys, one element at a time. The first time through the loop, the print command

print "$_  =  $ENV{$_}\n";

substitutes for the value of $_, and essentially runs this command:

print "EDITOR  =  $ENV{EDITOR}\n";

which results in this output:

EDITOR  =  vi

The foreach loop then continues it's processing until every key from the array %ENV has been processed.

ThinkGeek Cool Stuff Cheap

Accessing shell environment variables in Perl - Conclusion

Having associative arrays available in Perl makes something like accessing our shell environment variables very easy. Instead of having to deal with many different separate variable names, we simply work with one array which contains the contents of the

separate variables.

In the future we'll explain more about the magical powers of associative arrays, and how they can be great tools for getting a lot of work done with a minimal amount of coding.