Python – /bin/sh – non interactive usage from Python

pythonshell

I am invoking cmd from Python like this:

subpocess.Popen(['coffee'], shell=True)

which I belive is translated to:

/bin/sh -c "coffee"

From docs I have read that in non-interactive mode files like /etc/profile, /etc/bash.bashrc are not read and default $PATH is used (init $PATH). Am I wright? Is there the only way to add coffee to the $PATH is to copy it to /usr/local/bin?

Best Answer

You can modify the PATH environment variable in your Python script before starting the shell, i.e., some variant of:

import os

os.environ['PATH'] = '/some/new/path:%s' % os.environ['PATH']
subpocess.Popen(['coffee'], shell=True)

Note that setting shell=True is very often unnecessary, and you should be aware of the implications of doing so, especially if you are calling Popen using user-supplied data. The general problem is that data containing shell metacharacters (e.g., ">", or ";", "&") and so forth can cause unexpected behavior.

UPDATE: For example, if I have a script called /tmp/foo and I want to run this using subprocess.Popen, this works just fine:

>>> import os, subprocess
>>> os.environ['PATH'] = '/tmp:%s' % os.environ['PATH']
>>> subprocess.Popen('foo', shell=False)

If I don't set PATH, then I get the expected error:

OSError: [Errno 2] No such file or directory