Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subprocess.call or Subprocess.Popen cannot use executables that are in PATH (Linux/Windows)

I'm writing a programme that needs to run on both Linux and Windows and use executables (with parameters) that exist in the path. (Assumed)

Currently I'm having trouble running executables in windows using Subprocess.Call and Subprocess.Popen.

For a code like this, in windows 8

def makeBlastDB(inFile, inputType, dbType, title, outDir):
    strProg = 'makeblastdb'
    strInput = '-in ' + inFile
    strInputType = '-input_type ' + inputType
    strDBType = '-dbtype ' + dbType
    strTitle = '-title ' + title
    strOut = '-out ' + os.path.join(os.sep, outDir, title)
    cmd = [strProg, strInput, strInputType, strDBType, strTitle, strOut]
    result = Popen(cmd, shell=True)

I get the error message in console

'makeblastdb' is not recognized as an internal or external command,
operable program or batch file.

Even though I can run the same command using cmd.exe I get the same response with shell=False.

Any ideas on how I can run the command assuming that the executable is in PATH environment variable? Thanks

like image 615
Jacob Wang Avatar asked Feb 04 '13 01:02

Jacob Wang


People also ask

Why is subprocess not finding executable files in path?

It has nothing to do with subprocess finding executable files. Due to the differences in the underlying implementation, subprocess.Popen will only search the path by default on non-Windows systems (Windows has some system directories it always searches, but that's distinct from PATH processing).

What is a relative path in subprocess Popen?

A relative path in subprocess.Popen acts relative to the current working directory, not the elements of the systems PATH. If you run python subdir2/some_script.py from /dir then the expected executable location (passed to Popen) will be /dir/../subdir1/some_executable, a.k.a /subdir1/some_executable not /dir/subdir1/some_executable.

What is the use of subprocess in Linux?

The subprocess.popen () is one of the most useful methods which is used to create a process. This process can be used to run a command or execute binary. The process creation is also called as spawning a new process which is different from the current process.

Why doesn't Popen look at the path of a running Python program?

This means that Popen looks at the value of PATH as it was when Python launched (the Python that runs the Popen instantiation) and no amount of changing os.environ will help you fix that. Also, on Windows with shell=False, Popen pays no attention to PATH at all, and will only look in relative to the current working directory.


1 Answers

You can control the environment variables available in the spawned subprocess by passing a mapping with the env keyword argument. E.g.

proc = subprocess.Popen(args, env={'PATH': '/some/path'})

Or to inherit PATH from the system environment variable, without necessarily chucking in everything else from the system environment:

proc = subprocess.Popen(args, env={'PATH': os.getenv('PATH')})

It might be easier/simpler just to use an absolute path, though.

like image 113
wim Avatar answered Oct 12 '22 02:10

wim