Parseltongue
Parseltongue

Reputation: 11657

Subprocess.Call fails "The System Cannot Find the File Specified"

I have a .exe file called Manipula that takes as its source a .msu file. I can successfully run what I want through the command line like so:

"C:/Flow Check/Run Quick/Applications/Manipula.exe" "C:/Flow Check/Data Processing/BLAISE TO BLAISE.msu"

However, I cannot simulate this behavior in Python-- no matter what I use. I have tried os.system and subprocess.call and subprocess.Popen

If I run something like the following

p= subprocess.Popen("C:/Flow Check/Run Quick/Applications/Manipula.exe" "C:/Flow Check/Data Processing/BLAISE TO BLAISE.msu", stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
 print line,
retval = p.wait()

I get an error: The System Cannot Find the File Specified. I've triple-checked, the file is clearly there because it works when I run the commandline.

When I add shell=True to subprocess.Popen a new error appears that there is no directory C:/Flow, I think because the shell has a hard time processing spaces... I just don't know what's going on.

When I do os.system("C:/Flow Check/Run Quick/Applications/Manipula.exe" "C:/Flow Check/Data Processing/BLAISE TO BLAISE.msu") nothing happens.

Any ideas?

Upvotes: 4

Views: 20638

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1121904

You are not passing in two strings; you are passing in one string with no whitespace between. Python automatically concatenates adjacent strings with nothing but whitespace in between:

>>> "C:/Flow Check/Run Quick/Applications/Manipula.exe" "C:/Flow Check/Data Processing/BLAISE TO BLAISE.msu"
'C:/Flow Check/Run Quick/Applications/Manipula.exeC:/Flow Check/Data Processing/BLAISE TO BLAISE.msu'

Note how there is no space between .exe and C:/Flow.

Put the two strings in a list:

p = subprocess.Popen(["C:/Flow Check/Run Quick/Applications/Manipula.exe", "C:/Flow Check/Data Processing/BLAISE TO BLAISE.msu"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

Now Popen() will handle passing in correctly quoted strings to the underlying OS as one command.

Upvotes: 5

falsetru
falsetru

Reputation: 369074

Specify program and its arguments as list:

p = subprocess.Popen([
    "C:/Flow Check/Run Quick/Applications/Manipula.exe",
    "C:/Flow Check/Data Processing/BLAISE TO BLAISE.msu"],
    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

Writing string literals serially merges the strings:

>>> "abc" "xyz"
'abcxyz'

Upvotes: 6

Related Questions