Set an environment variable

C

Christian

Another question from a not even newbie:

In Unix you can set an environment variable with the command
export PYTHONPATH
but I would like to set the variable from at .py script.

So my question is:
How do I export an environment variable in a .py script?


Thanks

Chris
 
J

jepler

In Unix, you generally can't affect the environment of your parent program (in
a broad sense, which includes environment variables, current working directory,
opened files, effective user ID, etc).

You have two basic choices to achieve an effect like this. First, you can
start a subshell with the desired environment, something like (untested)
os.environ['VARIABLE'] = 'value'
os.system(os.environ['shell'])
(commands like 'su' work in this way)

Second, you can produce shell commands that have the effect of changing a
shell's environment when they are executed. Something like:
print "VARIABLE=value"
To use this, the user must write something like
eval `myscript.py`
instead of just
myscript.py
this can typically be encapsulated in a shell alias or function.
(commands like 'resize' (which sets the shell's idea of a terminal's size) work
this way)

Finally, you might be able to use an OS-specific interface like linux' ptrace
to change the actual contents of a calling process's memory. I didn't
immediately find an example of this, but on Linux it would consist of using
PTRACE_PEEKDATA and PTRACE_POKEDATA to locate the environment in another
process and modify it. The ptrace interface is not available from any standard
Python module, and isn't portable anyway. (though my manpage actually says
'CONFORMING TO SVr4, ..., X/OPEN, BSD 4.3' so maybe ptrace is more portable
than I believed)

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFDV4sxJd01MZaTXX0RAj4aAJ41BlvbrZxLNrhm+Ea5bgMyZOkVwQCglsLw
wFB6iqRqw3FRznozCpV5qh0=
=MqJa
-----END PGP SIGNATURE-----
 
E

Eric Brunel

Just use
os.system("export PYTHONPATH = %s" %("your_pythonpath"))

.... except it won't work: os.system will execute the command in a new process, so the environment variable change will only be visible in *this* process. Since you don't do anything else, the environment variable change will never be seen by anyone.

As for the OP's question, the short answer is "you can't": the Python interpreter will always be executed in a different process than the calling shell, and environment variable changes *never* impact the calling process on Unix.

The closest thing you can do is that:

-myScript.py--------------------------------------
print 'export MY_VARIABLE=value'
 
G

Grant Edwards

os.system("export PYTHONPATH = %s" %("your_pythonpath"))

No, that won't work.

That will set the environment variable in the shell spawned by
the os.system command. That shell will then immediately exit,
leaving the caller's environment unchanged.
 
M

Mike Meyer

Eric Brunel said:
-myScript.py--------------------------------------
print 'export MY_VARIABLE=value'
--------------------------------------------------

-myScript.sh--------------------------------------
python myScript.py > /tmp/chgvars.sh
. /tmp/chgvars.sh

It's simpler to use eval and command substitution:

eval $(python myScript.py)

<mike
 
C

Christian

The closest thing you can do is that:

-myScript.py--------------------------------------
print 'export MY_VARIABLE=value'
--------------------------------------------------

-myScript.sh--------------------------------------
python myScript.py > /tmp/chgvars.sh
. /tmp/chgvars.sh
--------------------------------------------------

Can I write a .py script that calls a .sh script that executes the
export command and then calls another .py script (and how would the
first .py script look)?

That would be much more what is my basic problem.


Thanks

Chris
 
E

Erik Max Francis

Christian said:
Can I write a .py script that calls a .sh script that executes the
export command and then calls another .py script (and how would the
first .py script look)?

No, the shell script that the Python program would invoke would be a
different process and so commands executed in it would have no effect on
the state of another.
 
C

Christian

Erik said:
No, the shell script that the Python program would invoke would be a
different process and so commands executed in it would have no effect on
the state of another.

So executing an .sh script that calls a .py script works different when
executed from a command promt than when executed from a starter .py script?
 
S

Sybren Stuvel

Mike Meyer enlightened us with:
It's simpler to use eval and command substitution:

eval $(python myScript.py)

This looks like the best solution to me.

Sybren
 
S

Steve Holden

Christian said:
Can I write a .py script that calls a .sh script that executes the
export command and then calls another .py script (and how would the
first .py script look)?

That would be much more what is my basic problem.
You can do what you suggest without shell scripting, unless I
misunderstand your intention: just set the environment variables you
want your Python script to see and then run it using os.system():

::::::::::::::
one.py
::::::::::::::
import os
os.environ['STEVE'] = "You are the man"
os.system("python two.py")
print "Ran one"
::::::::::::::
two.py
::::::::::::::
import os
print "STEVE is", os.environ['STEVE']
print "Ran two"
[sholden@headrat tmp]$ python one.py
STEVE is You are the man
Ran two
Ran one
[sholden@headrat tmp]$

Hope this helps.

regards
Steve
 
C

Chris F.A. Johnson

So executing an .sh script that calls a .py script works different when
executed from a command promt than when executed from a starter .py script?

No; it's always the same: an environment variable will only be
effective in the process in which it is set, and its children.

When you call another program, whether it's a shell script, python
script, or binary executable, you are starting a new process.
Environment variables set in that process will not affect its
parent (i.e., the process that called it).
 
C

Christian

Steve said:
::::::::::::::
one.py
::::::::::::::
import os
os.environ['STEVE'] = "You are the man"
os.system("python two.py")
print "Ran one"
::::::::::::::
two.py
::::::::::::::
import os
print "STEVE is", os.environ['STEVE']
print "Ran two"
[sholden@headrat tmp]$ python one.py
STEVE is You are the man
Ran two
Ran one
[sholden@headrat tmp]$

Hope this helps.

regards
Steve

Thanks Steve, you're quite right, you are the man. And thanks to all the
rest of you for your kind help and patient understanding. I have learned
quite a lot and is about to consider my self advanced to the status of
Python newbie.

So here is my final question:
Do I call the .sh script with a .py script like this:

os.system("/path/to/the/script/startupscript.sh")
 
S

Steve Holden

Christian said:
Steve Holden wrote:

::::::::::::::
one.py
::::::::::::::
import os
os.environ['STEVE'] = "You are the man"
os.system("python two.py")
print "Ran one"
::::::::::::::
two.py
::::::::::::::
import os
print "STEVE is", os.environ['STEVE']
print "Ran two"
[sholden@headrat tmp]$ python one.py
STEVE is You are the man
Ran two
Ran one
[sholden@headrat tmp]$

Hope this helps.

regards
Steve


Thanks Steve, you're quite right, you are the man. And thanks to all the
rest of you for your kind help and patient understanding. I have learned
quite a lot and is about to consider my self advanced to the status of
Python newbie.

So here is my final question:
Do I call the .sh script with a .py script like this:

os.system("/path/to/the/script/startupscript.sh")

Time you answered your own questions by trying things at the interactive
interpreter prompt!

regards
Steve
 
G

Grant Edwards

M

Mike Meyer

Grant Edwards said:
Bullshit. Are people being intentionally misleading??

No. Are you being intentionally - never mind.
And even Google knows the correct answer

http://www.google.com/search?hl=en&lr=&q=python+set+environment+variable

Follow the first hit.

The first hit is basically the solution presented above translated
from Unix to Windows: your python script writes the appropriate shell
commands into a file, then you get the command processor to process
that file. The Windows version carries this a step further by wrapping
it all up in a script to make it easy to run, but that's the only real
difference. Maybe the results order has changed since you looked?

Watch the recipe - I may add a Unix/sh solution.

<mike
 
G

Grant Edwards

No. Are you being intentionally - never mind.

Well, yes, probably.

My bad. I got links mixed up -- it wasn't the first one, it
was this one:

http://www.faqts.com/knowledge_base/view.phtml/aid/3298

There are two almost-equivalent tirival answers:

os.environment['foo'] = 'bar'

os.putenv('foo','bar')

I don't get why people seem to be obfuscating things with
multiple layers of shells or writing shell commands to to a
file and executing them.
Maybe the results order has changed since you looked?

No, I mixed them up.

My point: the OP wanted to know how to export an environment
variable to a child process. Either of the lines of code above
will do that, so what's with all the shellular shenanigans?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top