Ali250
Ali250

Reputation: 662

Replicate shell environment in python for executing bash commands

I'm trying to execute a bash script from inside python using the subprocess module. The problem is that this bash script relies on many environment variables that are set in my .bashrc file. What I want is for python subprocess to exactly replicate the environment that is setup when I launch a terminal window. So far I tried:

p = subprocess.Popen(args=['my-script.sh', '--additional_args'], stdout=subprocess.PIPE, env=os.environ.copy(), shell=True)
output_buffer, return_code = p.communicate()

But then read somewhere that even after doing shell=True, the .bashrc file is still not loaded, and that i should try something like this:

p = subprocess.Popen(args=['/bin/bash', '-i', '-c', 'my_script.sh', '--additional_args'], stdout=subprocess.PIPE)
output_buffer, return_code = p.communicate()

But with this function call, I get this error:

tput: No value for $TERM and no -T specified
bash: cannot set terminal process group (2071): Inappropriate ioctl for device
bash: no job control in this shell

Upvotes: 5

Views: 2273

Answers (2)

Alok
Alok

Reputation: 10544

xonsh shell should be useful for such mixing of bash and python

xonsh is a Python-powered shell that combines the flexibility of Python with > the convenience of a shell environment. It supports interactive use, > scripting, and seamless integration with existing Python libraries and tools.

Upvotes: 0

Miguel Ortiz
Miguel Ortiz

Reputation: 1482

This worked for me:

Bashrc

$ cat ~/.bashrc  |grep LOLO
export LOLO="/foo/bar"

Bash

#!/usr/bin/bash

echo $LOLO

Python

#!/usr/bin/python

import subprocess, os
my_env = os.environ.copy()
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen('/home/m.ortiz.montealegre/lolo/script.sh', env=my_env)

Output:

$ python script.py
/foo/bar

The thing is, if you add new values (aliases / variables) to your bashrc you'll need to restart your terminal in order to bashrc gets executed and make those changes availables in the environment.

I've found the references to do this here and here

Note: From a subshell process you can't set environment variables to the parent shell.

Upvotes: 3

Related Questions