1

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 Answer 1

1

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'}
Sign up to request clarification or add additional context in comments.

3 Comments

@hw-coder, source only works in a shell because it runs the commands within that shell process. It gives people the impression that it affects a parent process, but it doesn't. It's like an eval.
I added printenv in my bash script at the end and added subprocess.check_output(["source ./init.sh"],shell=True) in my python script . but still it is not able to get ROOT_DIR environment variable. Since I am new to python could you please show me an example it will be very much helpful. I didnt get what to do by this line in your answer "o grab the printenv output, then parse it and copy the environment variables you need back into the Python process's environ"
Did you look at the return value of check_output?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.