I've created Windows system variable using below code:
import os
os.environ['BJT'] = 'HELLO'
But I can't see it in Advanced settings \ system variables Also I can't see it when I try to print it:
import os
print(os.environ['BJT'])
I thought that when I create system variable using os.environ it is created exacly like when I do it in system settings. Is it possible to create system variable from python code and access it even when I restart computer?
You need to call the system (with admin privileges) to create a system variable, you can use subprocess:
import subprocess
subprocess.run(['setx', 'BJT', '"HELLO"', '/M'])
Prior to python3.5 you will need to use process.call instead
There is a misunderstanding with what environment is. It is just a mapping of (string) variables that a process can pass to its children. Specifically a process can change its own environment (which will be used by its future children) but this will not change its parent's environment, nor even the environment of its already existing children if any.
In addition, Windows provides system and user environment variables which are used as the initial environment of any process. This are not changet by os.environ nor by putenv but only from the Windows API or the shell command setx.
Related
A bit of a random problem here. I set an environment variable using PowerShell like this:
$env:GOOGLE_ELEVATION_API="the_api-key"
Then in python I attempt to read it with this simple script:
from os import environ
key = environ.get("GOOGLE_ELEVATION_API")
This returns None. If I query my environment variables in PowerShell it is there. If I query it through python with os.environ it is not.
None of the results I found make reference that this should be an issue, neither on the PowerShell side nor on python's side. I have not restarted my machine since I honestly do not believe this is what should be done. I did restart my IDE in the hope that it is somehow caching the environment but thankfully it does not.
Any pointers would be great!
Setting an environment variable via PowerShell's $env: namespace defines it for the current process only.
Any Python scripts invoked directly from a PowerShell session would see such variables, however, because child processes inherit the caller's environment variables.
To persistently define a Windows environment variable at the machine level that all processes see, you must use .NET APIs directly (as of PowerShell 7.1):
# Note: Requires ELEVATION, due to setting at the *machine* level.
[Environment]::SetEnvironmentVariable('GOOGLE_ELEVATION_API', 'the_api-key', 'Machine')
Note that only future PowerShell sessions will see this variable, and the need to restart an application in order for it to see the new variable typically also applies to other running applications.
(The exception are those applications that actively listen for the WM_SETTINGCHANGE message and refresh their environment in response, which is what the Windows GUI shell (explorer.exe) does.)
For more information about persistently setting environment variables on Windows, see this answer.
Inside of my scons script I execute another python script:
fs = env.Command('fs', None, 'python updatefs.py')
AlwaysBuild(fs)
Depends(fs, main)
In python script I am trying to access an environment variable:
import os
mode = os.environ['PROC_MODE']
The variable was previously set up in the shell:
export PROC_MODE='some_mode'
Python complain:
KeyError: 'PROC_MODE'
What is the proper way to propagate environment to an external script?
This is covered in lightly in the FAQ:
FAQ
Basically SCons constructs a clean reproducible set of environment variables so that differences in any user's environment won't break a build.
So if you want to propagate a particular variable from your shell you can explicitly do it as such:
env['ENV']['MY_VARIABLE']=os.environ['MY_VARIABLE']
If you wanted to progagate all environment variables you'd do this:
env['ENV'] = os.environ
Where env is your Environment()
Can it be changed for the current process by simply setting it to a new value like this?
os.environ['PYTHONHASHSEED'] = 'random'
It depends by what you mean.
If you mean to change the behaviour of the current interpreter than the answer is no:
Modifying os.environ isn't reliable, since in some OSes you cannot modify the environment (see the documentation for os.environ).
Environmental variables are checked only when launching the interpreter, so changing them afterwards will not have any effects for the current python instance. From the documentation:
These environment variables influence Python’s behavior, they are
processed before the command-line switches other than -E or -I.
(which implies they are only checked when launching the interpreter, well before any user-code is run).
AFAIK, the random hash seed cannot be set dynamically, so you have to restart the interpreter if you want to activate hash randomization.
If you mean to make new processes spawned by the current interpreter behave as if that value was set before, then yes, assuming that you are running on a platform that supports putenv. When spawning a new process, by default, it inherits the environment of the current process. You can test this using a simple script:
#check_environ.py
import os
import subprocess
os.environ['A'] = '1'
proc = subprocess.call(['python', '-c', 'import os;print(os.environ["A"])'])
Which yields:
$ python check_environ.py
1
Note that there exist known bugs in putenv implementations (e.g. in Mac OS X), where it leaks memory. So modifying the environment is something you want to avoid as much as possible.
I have one problem with os.environ. I set some variables in my bat file (for example):
set MYDIR=%CURDIR%
Then I use set command in command line of Windows to check it. Everything is fine, my variable was added. But!
Then I run my Python script and use os.environ['MYDIR'] or os.getenv('MYDIR') but my envorinment variable doesn't show up!
Why does it happen?
My OS - Windows 7 x64, Python 2.5.4
Thanks.
Set works on session level. WinXP, use SETX from support tools http://www.microsoft.com/en-us/download/details.aspx?id=18546 to permanently set env variable.
Or use MyComputer>Properties>Advanced>Environment Variables to set user- and system- level variables.
Never used PyCharm, but breef scan through docs shows that you might be able to set script-level environment variables within PyCharm, look here http://www.jetbrains.com/pycharm/webhelp/run-debug-configuration-python.html
I'm trying to use python to set environment variables that will persist in Pythons parent environment, even after python exits back to the shell, but will not persist once the parent shell is closed. Opening a new shell should require that the python script be run again in order to set the environment correctly.
Based off the recommendations from this post, I'm trying to do this using the win32com python library. Unfortunately, I have very little experience with the win32 api.
Basically, I need a way to get a handle to the current environment, and set environment variables in such a way that they will persist in python's parent environment, but will not persist after the parent environment exits.
The linked post tells how to change the default environment which will affect new processes. It manipulates registry values.
"A process can never directly change the environment variables of another process that is not a child of that process", says MS documentation. So you'll never reach your stated goal from within a child process, Python or not.
It is impossible to change the environment of the parent, by design. The best you can do is have your program emit commands that alter the environment, and then the caller of your program needs to eval the output of your command.