Section 3.8. Shell Environment Variables

3.8. Shell Environment Variables

Shell variables, sometimes known as environment variables, are made available to Python scripts as os.environ, a Python dictionary-like object with one entry per variable setting in the shell. Shell variables live outside the Python system; they are often set at your system prompt or within startup files and typically serve as system-wide configuration inputs to programs.

In fact, by now you should be familiar with a prime example: the PYTHONPATH module search path setting is a shell variable used by Python to import modules. By setting it once in your system startup files, its value is available every time a Python program is run. Shell variables can also be set by programs to serve as inputs to other programs in an application; because their values are normally inherited by spawned programs, they can be used as a simple form of interprocess communication.

3.8.1. Fetching Shell Variables

In Python, the surrounding shell environment becomes a simple preset object, not special syntax. Indexing os.environ by the desired shell variable's name string (e.g., os.environ['USER']) is the moral equivalent of adding a dollar sign before a variable name in most Unix shells (e.g., $USER), using surrounding percent signs on DOS (%USER%), and calling getenv("USER") in a C program. Let's start up an interactive session to experiment:

 >>> import os >>> os.environ.keys( ) ['WINBOOTDIR', 'PATH', 'USER', 'PP2HOME', 'CMDLINE', 'PYTHONPATH', 'BL*ER', 'X', 'TEMP', 'COMSPEC', 'PROMPT', 'WINDIR', 'TMP'] >>> os.environ['TEMP'] 'C:\\windows\\TEMP' 

Here, the keys method returns a list of set variables, and indexing fetches the value of the shell variable TEMP on Windows. This works the same way on Linux, but other variables are generally preset when Python starts up. Since we know about PYTHONPATH, let's peek at its setting within Python to verify its content (as I wrote this, mine was set to the roots of the book examples trees for the third and second editions):

 >>> os.environ['PYTHONPATH'] 'C:\\Mark\\PP3E-cd\\Examples;C:\\Mark\\PP2E-cd\\Examples' >>> >>> for dir in os.environ['PYTHONPATH'].split(os.pathsep): ...     print dir ... C:\Mark\PP3E-cd\Examples C:\Mark\PP2E-cd\Examples 

PYTHONPATH is a string of directory paths separated by whatever character is used to separate items in such paths on your platform (e.g., ; on DOS/Window, : on Unix and Linux). To split it into its components, we pass to the split string method an os.pathsep delimitera portable setting that gives the proper separator for the underlying machine.

3.8.2. Changing Shell Variables

Like normal dictionaries, the os.environ object supports both key indexing and assignment. As usual, assignments change the value of the key:

 >>> os.environ['TEMP'] = r'c:\temp' >>> os.environ['TEMP'] 'c:\\temp' 

But something extra happens here. In recent Python releases, values assigned to os.environ keys in this fashion are automatically exported to other parts of the application. That is, key assignments change both the os.environ object in the Python program as well as the associated variable in the enclosing shell environment of the running program's process. Its new value becomes visible to the Python program, all linked-in C modules, and any programs spawned by the Python process.

Internally, key assignments to os.environ call os.putenva function that changes the shell variable outside the boundaries of the Python interpreter. To demonstrate how this works, we need a couple of scripts that set and fetch shell variables; the first is shown in Example 3-4.

Example 3-4. PP3E\System\Environment\

 import os print 'setenv...', print os.environ['USER']                 # show current shell variable value os.environ['USER'] = 'Brian'             # runs os.putenv behind the scenes os.system('python') os.environ['USER'] = 'Arthur'            # changes passed to spawned programs os.system('python')           # and linked-in C library modules os.environ['USER'] = raw_input('?') print os.popen('python').read( ) 

This script simply changes a shell variable, USER, and spawns another script that echoes this variable's value, as shown in Example 3-5.

Example 3-5. PP3E\System\Environment\

 import os print 'echoenv...', print 'Hello,', os.environ['USER'] 

No matter how we run, it displays the value of USER in the enclosing shell; when run from the command line, this value comes from whatever we've set the variable to in the shell itself:

 C:\...\PP3E\System\Environment>set USER=Bob C:\...\PP3E\System\Environment>python echoenv... Hello, Bob 

When spawned by another script such as, though, gets whatever USER settings its parent program has made:

 C:\...\PP3E\System\Environment>python setenv... Bob echoenv... Hello, Brian echoenv... Hello, Arthur ?Gumby echoenv... Hello, Gumby C:\...\PP3E\System\Environment>echo %USER% Bob 

This works the same way on Linux. In general terms, a spawned program always inherits environment settings from its parents. Spawned programs are programs started with Python tools such as os.spawnv on Windows, the os.fork/exec combination on Unix and Linux, and os.popen and os.system on a variety of platforms. All programs thus launched get the environment variable settings that exist in the parent at launch time.[*]

[*] This is by default. Some program-launching tools also let scripts pass environment settings that are different from their own to child programs. For instance, the os.spawnve call is like os.spawnv, but it accepts a dictionary argument representing the shell environment to be passed to the started program. Some os.exec* variants (ones with an "e" at the end of their names) similarly accept explicit environments; see the os.exec call formats in Chapter 5 for more details.

From a larger perspective, setting shell variables like this before starting a new program is one way to pass information into the new program. For instance, a Python configuration script might tailor the PYTHONPATH variable to include custom directories just before launching another Python script; the launched script will have the custom search path because shell variables are passed down to children (in fact, watch for such a launcher script to appear at the end of Chapter 6).

3.8.3. Shell Variable Details

Notice the last command in the preceding examplethe USER variable is back to its original value after the top-level Python program exits. Assignments to os.environ keys are passed outside the interpreter and down the spawned programs chain, but never back up to parent program processes (including the system shell). This is also true in C programs that use the putenv library call, and it isn't a Python limitation per se.

It's also likely to be a nonissue if a Python script is at the top of your application. But keep in mind that shell settings made within a program usually endure only for that program's run and for the run of its spawned children. If you need to export a shell variable setting so that it lives on after Python exits, you may be able to find platform-specific extensions that do this; search or the Web at large.

Another subtlety: currently, changes to os.environ automatically call os.putenv, which runs the putenv call in the C library if the later is available on your platform; this exports the setting outside Python to any linked-in C code too. However, direct calls to os.putenv do not update os.environ to reflect the change, so os.environ changes are preferred.

Also note that environment settings are loaded into os.environ on startup and not on each fetch; hence, changes made by linked-in C code after startup may not be reflected in os.environ. Python does have an os.getenv call today, but it is translated into an os.environ fetch on most platforms, not into a call to getenv in the C library. Most applications won't need to care, especially if they are pure Python code. On platforms without a putenv call, os.environ can be passed as a parameter to program startup tools to set the spawned program's environment.

Programming Python
Programming Python
ISBN: 0596009259
EAN: 2147483647
Year: 2004
Pages: 270
Authors: Mark Lutz

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: