os.environ doesn't see some variables - python

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

Related

Cannot read environment variable set with PowerShell with os.environ.get

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.

os.getenv('CORENLP_HOME') returning None and os.environ['CORENLP_HOME'] returning KeyError but echo $CORENLP_HOME returns a path in terminal

I am aware a lot of similar questions exist but I am unable to understand what is happening here. I am trying to follow instructions for this Stanford CoreNLP python wrapper here, one of the steps is to set theCORENLP_HOME environment variable.
I ran the command:
export CORENLP_HOME=/path/to/stanford-corenlp-full-2018-10-05
Restarted the terminal, or actually added to my ~/.bash_profile. Now when I do a echo $CORENLP_HOME in the terminal I am able to see the path correctly. But on the other hand, if the corenlp wrapper code tries to find the same path through python code it returns None.
So I separately checked two python commands, the wrapper code uses os.getenv():
import os
print(os.getenv('CORENLP_HOME')) #prints None
print(os.environ['CORENLP_HOME']) #Throws a KeyError exception
MacOS version: 10.15.4;Python: 3.7.6
I don't have a very deep understanding of environment variables in general, I want to understand what is happening here, or if I am missing something simple. Happy to provide more information!
Environment variables are not global in the UNIX process model. Each process is provided a set of environment variables by the parent process that starts it. That is typically a copy of the parent's environment variables. If you are not starting pycharm from the shell that ran the export command pycharm won't see that shell's environment variables.
The behavior you describe means you are not starting pycharm from the shell that did the export CORENLP_HOME=/path/to/stanford-corenlp-full-2018-10-05.
P.S., The UNIX process model also means that a process cannot modify the environment variables of a different process.

Access to system variable by using os.environ

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.

Windows environment variable that runs a script

Is it possible to set a environment variable in Windows 7 that will run a python script when called? Couldn't do it when I tried.
No, there is no way to set an environment variable that calls a function when addressed. That's simply not something that environment variables can do.

Linux desktop file Exec doesn't used the user session

I have a python script file that works perfectly when I use it from the terminal.
Now I have created the following .desktop file in order to launch it easily:
[Desktop Entry]
Name=Test
GenericName=Test
Comment=My test script
Type=Application
Exec=/opt/test.py
Icon=/opt/test.png
Categories=Utils;
When I launch it the GTK window appear but clicking a button that call an init.d script make it working not properly.
Therefore adding Terminal=true make it working perfectly but I don't want to have that terminal open.
So I have then put the following code in order to log the environment variables:
import os
with open("/tmp/py_env.log", "w") as env_log:
env_log.write(str(os.environ))
and found differences.
So my question is how to write the .desktop file so that my application is running like if I start it from my terminal (without having an opened terminal :))
The problem is valid, but I think "replicating the terminal environment" is the wrong approach to solve it.
Indeed, what makes the application work is not the fact that it's launched from the terminal, it's that the terminal happens to have some environment variables which matter to your application.
Therefore, what you should aim for is to have those environment variables set properly at all times, rather than assuming the terminal environment will always happen to contain them all the time for all your users.
Thus, you should:
Check which environment variables are different between the two environments
Make a list of those which matter (i.e. those which would make the .desktop file work properly), and of what their value needs to be for the script to work
Either:
Create a wrapper script for your Python script, which initializes those environment variables properly, OR
Set those environment variables from inside the Python script itself.
this question is similar to .bashrc not read when shell script is invoked from desktop shortcut
either initialize your environment in ~/.bash_profile instead of
~/.bashrc
OR
make your *.desktop file call a wrapper that initializes your
environment - e.g. by sourcing ~/.bashrc (or whatever script is
responsible now).
the second solution is more specific (does not effect all other unrelated launches of your shell) in should thus be preferred.
Thanks anyone to have participate to this question.
I have solved this issue by implemented use of pkexec instead of gksudo.
pkexec seems to reuse the current user environment then I don't have this issue anymore.
Thanks.

Categories