Reputation: 87
I have a long bash script that at the end exports an environment variable, let's call it myscript.sh. I need to call this shell script from python code. As far as I know, the exported environment variable will be local, and won't be visible in python.
Is there a proper way to make it exported in the python environment as well?
Upvotes: 2
Views: 1565
Reputation: 5613
The general easiest way to get any information back from a child process is via the stdout pipe, which is very easily captured in the python exec method.
Get your script to print the info you want in a way that is easy to parse.
If you really want to see the env vars then you will need to print them out. If you don't want to modify the script you are trying to run then you could exec the script then dump the env, which is parseable.
. myscript && env
or if there is a particular env var you want:
. myscript && echo MYVAR="$myvar"
Note that this will be executed by python's default shell. If you want bash in particular, or you want the hashbang of your script to be honoured, that takes more effort. You could scrape the hashbang yourself, for example, but the env printing trick will only work trivially with shells - hashbangs may refer to other clevernesses such as sed/awk
To avoid nesting shell invocations, you could call subprocess.Popen with, eg ["/bin/bash", "-c", ". myscript && echo MYVAR=\"$myvar\""]
and shell=False
I added quotes to cover some cases where the var contains wildcard characters. Depending on the content of the variables printed, this may be good enough. If you expect the var to contain multi lines or perhaps the string MYVAR= or feel that the value set by the script is unconstrained, then you might need to do something more complex to ensure the output is preserved, as described by CD. It will also be marginally more difficult to parse from python.
Upvotes: 0
Reputation: 69188
You can use env -0
in your script to print all environment variables, separated with a null char as newline might be problematic if it's contained in some variable value.
Then from python you can set the process environment using this
import os
import subprocess
for k,v in filter(lambda p: len(p)==2, map(lambda e:e.decode().split('='), subprocess.run('script', check=True, capture_output=True).stdout.split(b'\x00'))):
os.environ[k]=v
Upvotes: 1