【问题标题】:Python - Windows - Popen(shlex.split(command), shell=False causes OSError: [Errno 2] No such file or directoryPython - Windows - Popen(shlex.split(command), shell=False 导致 OSError: [Errno 2] No such file or directory
【发布时间】:2014-05-22 13:55:54
【问题描述】:

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

【问题讨论】:

  • 您尝试通过指定可执行文件的路径来运行命令。 /usr/local/itms/share/iTMSTransporter.woa/iTMSTransporter 是文件系统中的路径。在 Windows 中,文件系统路径以驱动器号开头。这不可能是 Windows 上的有效路径。因此出现了错误,我想说的很清楚。
  • 对不起,你是对的!我的意思是将路径更改为 Windows 路径,我已经这样做了。我已经更新了问题。
  • 你应该转义命令并且不要使用波浪号:command = "\"C:\\program files\\itms\\iTMSTransporter.exe\" ...
  • 系统提示你路径还是错误的。我不确定这里的 Windows 错误消息,但我很确定如果问题是文件无法访问或无法执行,那么错误消息将是不同的。 progra~2 字符串可能无效。
  • progra~2 在 shell=True 的情况下可以正常工作,但仍然无法正常工作。

标签: python windows popen


【解决方案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() 将正确处理此路径。

【讨论】:

  • 我尝试了上面的建议,但我仍然得到同样的错误。请问有什么想法吗?
【解决方案2】:

这可能来得有点晚,但也许对其他有类似问题的人有帮助。

开始之前:我通常在处理 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'

正如您在其他答案的 cmets 中所述,替换斜杠并不能解决您的问题,您的实际问题可能在于您在 -f-o 中传递给脚本的路径。也许您将这些路径传递给的脚本需要反斜杠字符或希望在路径中包含驱动器号。 – 无论如何,想知道您在过去 6 年中是否找到了解决方案,以及这个解决方案是什么。


更多选项

您还可以使用pathlib(用于操作系统感知路径格式的python3 标准库)Path 提供as_posix() 方法将路径转换为带有正斜杠的字符串。这将导致您的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'

或者,以下 - In [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'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-17
    • 2019-03-25
    • 2016-06-07
    • 2017-07-05
    • 2018-11-20
    • 2018-07-24
    • 1970-01-01
    • 2018-01-21
    相关资源
    最近更新 更多