0

I am running this code which works fine in OSX but causes an error on Windows:

command = "C:\\progra~2\\itms\\iTMSTransporter -m verify -f /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp -u username -p password -o /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt -s provider -v eXtreme"
self.process1 = Popen(shlex.split(command), shell=False, stdin=PIPE)

The error I am recieving on Windows is:

WindowsError: [Error 2] The system cannot find the file specified

Why is it giving me this error on Windows?

speedyrazor
  • 3,127
  • 7
  • 33
  • 51
  • 3
    You try to run a command by specifying the path to an executable. `/usr/local/itms/share/iTMSTransporter.woa/iTMSTransporter` is a path in a file system. In Windows, file system paths start with a drive letter. There is no way that this is a valid path on Windows. Hence the error, which is pretty clear I would say. – Dr. Jan-Philip Gehrcke May 22 '14 at 13:58
  • Sorry, you are right! I meant to change the path to a windows path, which I have done. I have updated the question. – speedyrazor May 22 '14 at 14:03
  • you should escape the command and do not use the tilde: command = "\"C:\\program files\\itms\\iTMSTransporter.exe\" ... – Leonardo Bernardini May 22 '14 at 14:05
  • The system is telling you that the path is still wrong. I am not sure about Windows error messages here, but I am pretty sure that if the problem was that the file cannot be accessed or cannot be executed, then the error message would be a different one. Likely the `progra~2` string is invalid. – Dr. Jan-Philip Gehrcke May 22 '14 at 14:05
  • progra~2 work fine with shell=True, still can't get it working. – speedyrazor May 22 '14 at 14:44
  • Leonardo, I tried command = "\"C:\\program files\\itms\\iTMSTransporter.exe\" but still get the same error. – speedyrazor May 22 '14 at 15:00

2 Answers2

2

Your shlex.split() destroys your path because of removing \ characters. Let's check:

import shlex
command = "C:\\progra~2\\itms\\iTMSTransporter -m verify -f  Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp -u username -p password -o /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt -s provider -v eXtreme"
print shlex.split(command)

['C:progra~2itmsiTMSTransporter', '-m', 'verify', '-f', '/Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp', '-u', 'username', '-p', 'password', '-o', '/Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt', '-s', 'provider', '-v', 'eXtreme']

As you can see, path to executable is incorrect (C:progra~2itmsiTMSTransporter), so Popen can't find it.

Change your path separator to /, which is safe in both Linux/Windows environments:

command = "C:/progra~2/itms/iTMSTransporter -m verify -f  Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp -u username -p password -o /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt -s provider -v eXtreme"
print shlex.split(command)

['C:/progra~2/itms/iTMSTransporter', '-m', 'verify', '-f', 'Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp', '-u', 'username', '-p', 'password', '-o', '/Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt', '-s', 'provider', '-v', 'eXtreme']

Popen() will handle this path correctly.

Gabriel M
  • 710
  • 4
  • 7
1

This might come a bit late, but maybe it is helpful for others having similar problems.

Before we start: I usually tend to use raw strings when handling windows paths to facilitate copy pasting as it accepts single backslash characters:

In [0]: "C:\\path\\to\\folder" == r"C:\path\to\folder"
Out[0]: True

As mentioned in Gabriel M's answer, the problem might come from shlex swallowing the backlashes. In this answer I want to provide a solution other than replacing the backslashes by slashes.

In [1]: import shlex

In [2]: command = r"C:\progra~2\itms\iTMSTransporter -m verify 
   ...: -f /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp -u username -p password
   ...: -o /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt -s provider -v eXtreme"

In [3]: shlex.split(command)[0]
Out[3]: 'C:progra~2itmsiTMSTransporter'

A simple solution to keep the backslashes is to pass the posix=False option to shlex.split():

In [4]: shlex.split(command, posix=False)[0]
Out[4]: 'C:\\progra~2\\itms\\iTMSTransporter'

As you stated in the other answer's comments, replacing slashes did not solve your problem, it might be that your actual problem lies in the paths that you pass to your script in -f and -o. Maybe the script that you pass those paths to expects backslash characters or wants to have the drive letter in the path. – In any case, it would be interesting to know if you have found a solution to this in the last 6 years, and what this solution was.


Further options

You can also use pathlib (an python3 standard library for OS aware path formatting) who's Path provide an as_posix() method to convert the path to a string with forward slashes. This will result in forward slashes in your shlex.split() output. This might be most useful if your path comes from a variable, and is not directly hard coded (in the latter case you might just change the (back)slashes):

In [5]: from pathlib import Path

In [6]: command = Path(r"C:\progra~2\itms\iTMSTransporter").as_posix() + " -m verify 
   ...: -f /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp -u username -p password
   ...: -o /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt -s provider -v eXtreme"

In [7]: shlex.split(command)[0]
Out[7]: 'C:/progra~2/itms/iTMSTransporter'

Alternatively, the following – an improved version of In [4] – is something that should work on either OS. In this case posix is determined via os.name. This also relies on the use of pathlib for OS aware path formatting.

In [8]: import os

In [9]: command = str(Path(r"C:\progra~2\itms\iTMSTransporter")) + " -m verify 
   ...: -f /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp -u username -p password
   ...: -o /Volumes/Stuff/Temp/TMP_S_0_V_TV2.itmsp/LOGFILE.txt -s provider -v eXtreme"

In [10]: shlex.split(command, posix=(os.name == "posix"))[0]
Out[10]: 'C:\\progra~2\\itms\\iTMSTransporter'
lcnittl
  • 233
  • 1
  • 14