Python-Windows-Popen(shlex.split(command),shell=False会导致OSError:[Errno 2]没有这样的文件或目录

Python-Windows-Popen(shlex.split(command),shell=False会导致OSError:[Errno 2]没有这样的文件或目录,python,windows,popen,Python,Windows,Popen,我正在运行此代码,该代码在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.proc

我正在运行此代码,该代码在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上给我这个错误?

您的
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()

在开始之前:我通常倾向于在处理windows路径时使用原始字符串,以便于复制粘贴,因为它接受单个反斜杠字符:

In [0]: "C:\\path\\to\\folder" == r"C:\path\to\folder"
Out[0]: True
如中所述,问题可能来自
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()

正如您在另一个答案的评论中所述,替换斜杠并不能解决您的问题,您的实际问题可能在于您在
-f
-o
中传递给脚本的路径。可能是要将这些路径传递给预期的反斜杠字符,或者希望在路径中包含驱动器号。总之,这是正确的如果你在过去6年里找到了解决his的方法,以及这个方法是什么,那会很有趣


其他选择 您还可以使用
pathlib
(用于操作系统感知路径格式化的python3标准库)提供
as_posix()
方法,将路径转换为带正斜杠的字符串。这将导致
shlex.split()中出现正斜杠
output。如果路径来自变量,并且不是直接硬编码的(在后一种情况下,您可以只更改(后)斜杠),则此选项可能最有用:

或者,以下是一个改进版的
[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'

您试图通过指定可执行文件的路径来运行命令。
/usr/local/itms/share/iTMSTransporter.woa/iTMSTransporter
是文件系统中的路径。在Windows中,文件系统路径以驱动器号开头。这在Windows上不可能是有效路径。因此,我想说的是,错误非常明显。对不起,您是对的!我想将路径更改为windows路径,我已经这样做了。我已经更新了问题。您应该退出该命令,不要使用tilde:command=“\”C:\\program files\\itms\\iTMSTransporter.exe\"…系统告诉您路径仍然错误。我不确定此处的Windows错误消息,但我非常确定,如果问题是文件无法访问或无法执行,则错误消息将是另一个错误消息。可能
progra~2
字符串无效。progra~2在shell=True,sti的情况下工作正常我无法让它工作。我尝试了上面的建议,但仍然得到相同的错误。有什么想法吗?
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'
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'