0
votes

How to source the bash file in python script and use the environment variable (which is set in bash script) inside python? When I am removing source file from python script and sourcing it outside the ROOT_DIR which is an environment variable in bash script is able to recognise by my python script. Could you please suggest how can I achieve sourcing the bash script and use the variables there in python script. An example I have given below.

#!/usr/bin/python3

import sys, getopt
import os

def main(argv):

   os.system('source ./init.sh')


   root_dir =  os.environ['ROOT_DIR']
if __name__ == "__main__":
   main(sys.argv[1:])

The error I got is below:

Sourcing Successfully Done... Traceback (most recent call last):
File "test.py", line 213, in main(sys.argv[1:]) File "test.py", line 33, in main root_dir = os.environ['ROOT_DIR'] File "/usr/lib64/python3.6/os.py", line 669, in getitem raise KeyError(key) from None KeyError: 'ROOT_DIR'

My bash script is as below:

export ROOT_DIR=${PWD}
export TB_DIR=${PWD}/..
1

1 Answers

1
votes

It won't work like that.

The shell script is run in a subprocess, which gets its own copy of the parent process's environment table.

You'd need to add e.g. printenv at the end of the shell script, then use e.g. subprocess.check_output(..., shell=True) to grab the printenv output, then parse it and copy the environment variables you need back into the Python process's environ.

Or, preferably, use a machine-readable, declarative format for that configuration to begin with, instead of an arbitrary program :)

Example

Assuming shell.sh is the script to run, and it declares export FOOFOO=bar:

output = subprocess.check_output("./shell.sh", shell=True)
# Parse the `printenv` output
exported_vars = dict(
    line.split("=", 1)
    for line in output.decode().splitlines()
    if line
)
# Filter to keep only variables that have new or changed values
changed_vars = {
    key: value
    for (key, value) in exported_vars.items()
    if value != os.environ.get(key)
}
pprint.pprint(changed_vars)

the output in repl.it is

{'COLUMNS': '93',
 'FOOFOO': 'bar',
 'LINES': '64',
 'SHLVL': '1',
 '_': '/usr/bin/printenv'}