Mailing List Archive

'sourcing' Python scripts?
Dear Python experts,

this might be a unix rather than a Python problem, but I need to set
environment variables from a Python program *in the parent process*
that is running the Python script ( a la os.environ['BAR'] = 'foo' ).
In other words, I want to achieve the equivalent of 'sourcing' the
Python script. Can this be done? Even better would be a solution that
also works on the various WinAbominations... (well, NT at least)

Haimo G. Zobernig

Haimo.Zobernig@cern.ch
'sourcing' Python scripts? [ In reply to ]
Hello!

On Wed, 28 Apr 1999, Haimo G. Zobernig wrote:
> this might be a unix rather than a Python problem, but I need to set

Yes, it is of unix...

> environment variables from a Python program *in the parent process*
> that is running the Python script ( a la os.environ['BAR'] = 'foo' ).
> In other words, I want to achieve the equivalent of 'sourcing' the
> Python script. Can this be done? Even better would be a solution that
> also works on the various WinAbominations... (well, NT at least)

Don't know about NT, sorry. Will talk about unix.

Preface.
When you run a program (python script, e.g.), shell (that run the
program) forks and looses any connection to running program. The program
may do anything it wants (change current directory, for example), but all
chnages are local to the program's process (and children). Parent shell
does not know anything. This is the nature of multitasking environment.
For the shell, the only way to set environment (change directory, etc.)
is to give commands to that shell.

Well, now you want to run a program, and pass the results to a parent
shell. Here is how you should do it.
First, your program should write the shell commands to stdout. Second,
you need to ask the shell to process these commands:
(in shell command line) eval `myscript.py`
Note "eval" and backticks. Backticks in most (if not all) unix shells mean
"run the command and save its stdout". Eval processes saved stdout as
shell commnads.

Please note. There are two different kinds of shell syntax - Bourne
shell and C shell.
Usually any program that intended to run under such conditions, can
output two different set of commands - for Bourne shell and for C shell.
Some programs parse SHELL env var (if it matches /bin/*csh - it is a
C-shell variant, else it is Bourne shell), some programs can be controlled
with command line switch (-c for c-shell, nothing for bourne shell). Choose
your method, but please do not force your users to switch a shell just
because your program can only work with one shell but not another.

Example:

(in python program my_prog.py):

if under_cshell: # expect C shell
print "setenv MY_VAR1 value1"
print "setenv MY_VAR2 value2"
else: # expect Bourne shell
print "MY_VAR1=value1"
print "MY_VAR2=value2"
print "export MY_VAR1 MY_VAR2"

(in shell):
eval `my_prog.py`

> Haimo G. Zobernig
> Haimo.Zobernig@cern.ch

Oleg.
----
Oleg Broytmann National Research Surgery Centre http://sun.med.ru/~phd/
Programmers don't die, they just GOSUB without RETURN.
'sourcing' Python scripts? [ In reply to ]
Haimo G. Zobernig <Haimo.Zobernig@cern.ch> wrote:
: Dear Python experts,

: this might be a unix rather than a Python problem, but I need to set
: environment variables from a Python program *in the parent process*
: that is running the Python script ( a la os.environ['BAR'] = 'foo' ).
: In other words, I want to achieve the equivalent of 'sourcing' the
: Python script. Can this be done? Even better would be a solution that
: also works on the various WinAbominations... (well, NT at least)

: Haimo G. Zobernig

: Haimo.Zobernig@cern.ch

Are both programs written in Python?

If so, then you could make something like:

def environ_save(filename, environ):
file = open(filename, 'w')
lines = [ 'environ = {}\n' ]
for (key, value) in environ.items():
lines.append('environ[%s] = %s\n' % (repr(key), repr(value)))
open(filename, 'w').writelines(lines)

def environ_load(filename, other_environ):
execfile(filename) # this creates a local variable called 'environ'
for (key, value) in environ.items():
other_environ[key] = value

Call "environ_save" from the child process, and "environ_load" from the
parent. Also, this relies on the data being reproducable from repr().
Which, if it is from os.environ, it should be. :)

Now, I haven't tested this, but I don't see any problems. A pickle
solution can be left to the reader.

-Arcege
'sourcing' Python scripts? [ In reply to ]
Haimo G. Zobernig <Haimo.Zobernig@cern.ch> wrote in
<372713AD.6ABA444@cern.ch>:

>Dear Python experts,
>
>this might be a unix rather than a Python problem, but I need to set
>environment variables from a Python program *in the parent process*
>that is running the Python script ( a la os.environ['BAR'] = 'foo' ).
>In other words, I want to achieve the equivalent of 'sourcing' the
>Python script. Can this be done? Even better would be a solution that
>also works on the various WinAbominations... (well, NT at least)

About the only way to make this work would be to make the python program
output a shell script that sets the environment variables and 'source' the
output. Something similar should work on NT/95 although you would have to
output appropriate syntax for the system in use.

For example, the following abomination works on Windows NT 4 SP4:
--------- something.bat or something.cmd --------------
@echo off
set XYZZY="------------------"
echo XYZZY is %XYZZY%
for /F "tokens=*" %%i in ('d:\progra~1\python\python.exe test.py') do %%i
echo XYZZY is %XYZZY%
-------------------------------------------------------

---------- test.py -------------------
print "SET XYZZY=Hello World"
--------------------------------------


--
Duncan Booth duncan@dales.rmplc.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
http://dales.rmplc.co.uk/Duncan