在 Python 中使用 subprocess.call('dir', shell=True) 时找不到指定的文件

Posted

技术标签:

【中文标题】在 Python 中使用 subprocess.call(\'dir\', shell=True) 时找不到指定的文件【英文标题】:Cannot find the file specified when using subprocess.call('dir', shell=True) in Python在 Python 中使用 subprocess.call('dir', shell=True) 时找不到指定的文件 【发布时间】:2013-12-18 06:49:31 【问题描述】:

在安装了 32 位 python 2.7 的 64 位系统中,我正在尝试执行以下操作:

import subprocess
p = subprocess.call('dir', shell=True)
print p

但这给了我:

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    p = subprocess.call('dir', shell=True)
  File "C:\Python27\lib\subprocess.py", line 522, in call
    return Popen(*popenargs, **kwargs).wait()
  File "C:\Python27\lib\subprocess.py", line 709, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 957, in _execute_child
    startupinfo)
  WindowsError: [Error 2] The system cannot find the file specified

如果我在终端做...

dir

...它当然会打印当前文件夹的内容。

我已尝试将 shell 参数更改为 shell=False。

编辑:实际上我无法使用subprocess.call() 调用路径上的任何可执行文件。声明 p = subprocess.call('dir', shell=True) 在另一台机器上运行良好,我认为它是相关的。

如果我这样做

 subprocess.call('PATH', shell=True)

然后我得到

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    subprocess.call('PATH', shell=True)
  File "C:\Python27\lib\subprocess.py", line 522, in call
     return Popen(*popenargs, **kwargs).wait()
  File "C:\Python27\lib\subprocess.py", line 709, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 957, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

如果我这样做:

import os
print os.curdir

然后我得到

.

以上所有操作都在以管理员模式启动的终端中执行。

【问题讨论】:

dir 不是可执行文件,它是一个仅限控制台的命令。为什么不改用os.listdir() 奇怪,代码在 ubuntu、rhel、win xp、win 7 上对我有用 实际上我无法调用路径上的任何可执行文件。声明 p = subprocess.call('dir', shell=True) 在另一台机器上运行良好,我认为它是相关的。我想尽可能地简化我的问题,所以我只提出了带有“dir”的示例。我更新了问题... 您是从控制台还是从某个 IDE 运行脚本? 感谢您迄今为止的所有帮助。我很感激!我已经根据您的想法更新了我的问题。 【参考方案1】:

我认为您的COMSPEC 环境变量可能有问题:

>>> import os
>>> os.environ['COMSPEC']
'C:\\Windows\\system32\\cmd.exe'
>>> import subprocess
>>> subprocess.call('dir', shell=True)

    (normal output here)

>>> os.environ['COMSPEC'] = 'C:\\nonexistent.exe'
>>> subprocess.call('dir', shell=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\Python27\lib\subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "c:\Python27\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "c:\Python27\lib\subprocess.py", line 896, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

我通过深入研究subprocess.py 并查看_execute_child 函数发现了这个潜在问题,正如回溯所指出的那样。在那里,您会发现一个以 if shell: 开头的块,它将在环境中搜索所述变量并使用它来创建用于启动进程的参数。

【讨论】:

不错!这做到了... COMSPEC 变量设置为 %SystemRoot%\system32\cmd.exe;%SystemRoot%\system32\WindowsPowerShell\v1.0; 将其更改为 %SystemRoot%\system32\cmd.exe; 现在它工作正常。谢谢! 有趣。我从未见过有多个值的COMSPEC 集合——如果这确实有效,那么可能值得针对subprocess 提交一个错误。很高兴我能帮助你! ? 我安装 Windows Management Framework (microsoft.com/en-us/download/details.aspx?id=34595) 后出现的问题。之前我不知道 COMSPEC 变量的值,但之后它指向 cmd.exe 和 powershell.exe。根据en.wikipedia.org/wiki/ComSpec COMSPEC 变量应该只指向一个路径?正确的?也许 WMF 的安装过程做了一些奇怪的事情,或者你的意思是子进程应该处理 COMSPEC 变量中的多个路径? 我认为——特别是如果微软软件以这种方式更改COMSPEC(意味着它是有效的)——subprocess 应该能够处理它,是的。***的知识似乎已经过时了。 对我来说,值已经是 os.environ['COMSPEC'] 'C:\\Windows\\system32\\cmd.exe'............ ..我在詹金斯上运行这个.......不适合我............深入研究它【参考方案2】:

在投反对票之前,请注意问题是在我发布此答案后编辑的。

我觉得os.listdir更适合你的情况:

>>> import os
>>> os.listdir()
['1.txt', '2.txt', '3.txt', 'DLLs', 'Doc', 'e.txt', 'include', 'Lib', 'libs', 'LICENSE.txt', 'm.txt', 'msvcr100.dll', 'NEWS.txt', 'py.exe', 'python.exe', 'python33.dll', 'pythonw.exe', 'pyw.exe', 'README.txt', 'Scripts', 't.txt', 'tcl', 'Tools']

如果你想在命令行中运行它,并且只是想调用它,你可以使用os.sytem

os.system('dir')

这将运行命令,但它返回 0 并且您无法存储它。

【讨论】:

实际上我想调用一个可执行文件,但这也不起作用。我已经更新了我的问题...【参考方案3】:

如果除了我之外的其他人没有立即在 (3.4) docs 中看到这个:

在 shell=True 的 Windows 上,COMSPEC 环境变量指定 默认外壳。唯一需要指定 shell=True on Windows 是您希望执行的命令内置于 外壳(例如目录或副本)。您不需要 shell=True 来运行批处理 文件或基于控制台的可执行文件。

注意在使用 shell=True 之前阅读Security Considerations 部分。

【讨论】:

它可能应该是对已接受答案的编辑【参考方案4】:

使用 Shell=True,它对我有用。

【讨论】:

以上是关于在 Python 中使用 subprocess.call('dir', shell=True) 时找不到指定的文件的主要内容,如果未能解决你的问题,请参考以下文章

在 python 中使用 soffice,Command 在终端中有效,但在 Python 子进程中无效

python 使用pymongo在python中使用MongoDB的示例

在 python 中使用命令行时出现语法错误

python 在python中使用全局变量

如何在 Python 3.x 和 Python 2.x 中使用 pip

在Python中使用Redis