The way you access and modify Unix environment variables in Python programs is generally through
os.environ
; Python 3 being Python 3, sometimes you need
os.environb
. In Unix, what can go in the environment is somewhat fuzzy and while Python has some issues with character encodings, it's otherwise surprisingly liberal in a number of ways.
The first way that os.environ is liberal is that it allows environment variables to have blank values:
>>> os.environ["FRED"] = ""
>>> subprocess.run("printenv")
[...]
FRED=
[...]
It's possible to do this with some Unix shells as well, but traditionally environment variables are generally assumed to have non-blank values. Quite a lot of code is likely to assume that a blank value is the same as the variable being unset, although in Python you can tell the difference since
os.environ
raises
KeyError
if the environment variable doesn't exist at all.
A bigger way that os.environ is liberal is that it will allow you to use non-traditional characters in the names of environment variables:
>>> os.environ["FRED/BAR"] = "Yes"
>>> subprocess.run("printenv")
[...]
FRED/BAR=Yes
On Unix, setting an environment variable uses
setenv()
, which generally only requires that you avoid '='. Python specifically checks for an '=' in your name so that it can generate a specific error, and otherwise passes things through.
Python itself doesn't particularly restricted environment variable names beyond that. As a result you can do all sorts of odd things with environment variable names, including putting spaces and Unicode into them (at least in a UTF-8 environment). Some or many of these environment variables won't be accessible to a shell program, but not everything that interprets the environment follows the shell's rules.
The case where this came up for me recently was in Dovecot post-login scripting , which in some cases can require you to create environment variables with '/' in their names. Typical shells disallow this, but I was quite happy to find that Python was perfectly willing to go ahead and everything worked fine.