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
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).
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With