我正在运行此代码,该代码在OSX中运行良好,但在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)
我在Windows上收到的错误是:
WindowsError: [Error 2] The system cannot find the file specified
为什么它在Windows上给我这个错误?
答案 0 :(得分:1)
由于删除\字符,您的shlex.split()
会破坏您的路径。我们来看看:
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']
如您所见,可执行文件的路径不正确(C:progra~2itmsiTMSTransporter
),因此Popen无法找到它。
将您的路径分隔符更改为/
,这在Linux / 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"
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()
将正确处理此路径。
答案 1 :(得分:0)
这可能会晚一点,但也许对其他有类似问题的人很有帮助。
开始之前:我通常在处理Windows路径时倾向于使用原始字符串,以方便复制粘贴,因为它接受单个反斜杠字符:
In [0]: "C:\\path\\to\\folder" == r"C:\path\to\folder"
Out[0]: True
如Gabriel M's answer中所述,问题可能来自shlex
吞下了反冲。在这个答案中,我想提供一种解决方案,而不是用斜杠代替反斜杠。
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'
保持反斜杠的简单方法是将posix=False
选项传递给shlex.split()
:
In [4]: shlex.split(command, posix=False)[0]
Out[4]: 'C:\\progra~2\\itms\\iTMSTransporter'
正如您在另一个答案的注释中所述,替换斜杠不能解决您的问题,这可能是您的实际问题在于您在-f
和-o
中传递给脚本的路径。也许要编写脚本,您将那些路径传递给期望的反斜杠字符,或者想在路径中包含驱动器号。 –无论如何,如果您在过去6年中找到了他的解决方案以及该解决方案是什么,将会很有趣。
您还可以使用pathlib
提供Path
方法的as_posix()
(用于操作系统识别路径格式的python3标准库)来将路径转换为带正斜杠的字符串。这将导致shlex.split()
输出中的正斜杠。如果您的路径来自变量,并且没有直接进行硬编码(在后一种情况下,您可能只需更改(反)斜杠),则这可能最有用:
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'
或者,以下内容– [4]
的改进版本–在两种操作系统上均应适用。在这种情况下,posix
是通过os.name
确定的。这还取决于使用pathlib
进行操作系统感知的路径格式化。
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'