0

I have a shell script with the below content

$cat sample.sh
export greet="hello"
echo $greet

I have a python script where I want to call the bash script and use the exported environment variable.

$cat try.py
import os
os.system(". /tmp/sample.sh")
print("Greet from python : "+os.environ['greet'])

The above script doesn't retrieve the environment variable 'greet'. Also tried using subprocess, but the env variable is not available in python. Looks like its shell context related. https://www.shell-tips.com/bash/source-dot-command/ Any ideas?

NullPointer
  • 241
  • 1
  • 2
  • 7
  • 1
    Only a parent shell can export variables to its children, the other way around is not possible. Python here is the parent, and the shell created for executing `. /tmp/sample.sh` is the children. – oguz ismail Jul 29 '20 at 13:44
  • 1
    @NullPointer : You have to pass the value of the environment variable somehow to the caller. If stdout (as one of the answers suggested) is not an option, because you need stdout for a different purpose, write it to a file and read this file from Python. To make your shell script more flexible to use, you can pass to it the file name. BTW, sourcing the script (with `.`) as you are doing it, does not make sense in your set-up, because the parent isn't bash. – user1934428 Jul 29 '20 at 13:51

1 Answers1

0

The reason it is that you are using environment wrongly, but you did in a subtle way.

Environments are shared only to children, and os.system() executes (in a children) a new process, and such process will get greet. Unfortunately the children will exit and will be destroyed at the end of the command. So in the next line, you have just the original environment, which it is not affected by sample.sh.

This is a very good security measure (that children processes will not modify environment of parent). If you want to pass data, you should use stdout in shell, e.g. with subprocess (you get example in Python Library documentation.

Giacomo Catenazzi
  • 8,519
  • 2
  • 24
  • 32
  • "Subtle" because `. command` is used to save environment variable "in the parent" (which isn't really the parent, it is just executed on the same environment, not the common "on children"). But in this case os.system execute the shell, and the shell execute the sample.sh, so still in two different environments – Giacomo Catenazzi Jul 29 '20 at 13:48
  • I love the downvotes, without explanation. (I gave my answer 13 second before the first comment, so it is not a copy-cat), and the duplicate is wrong. The "solution" propose a different (and often unusable workaround: calling rest of python from shell: someone likes to give complex solution to simple problems). – Giacomo Catenazzi Jul 30 '20 at 08:07