Home > Net >  How to run shell script from python and use its exported environment variables?
How to run shell script from python and use its exported environment variables?

Time:02-04

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?

CodePudding user response:

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

CodePudding user response:

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

  • Related