如何从 Python 执行程序? os.system 由于路径中的空格而失败

Posted

技术标签:

【中文标题】如何从 Python 执行程序? os.system 由于路径中的空格而失败【英文标题】:How do I execute a program from Python? os.system fails due to spaces in path 【发布时间】:2010-09-17 06:28:15 【问题描述】:

我有一个 Python 脚本需要执行外部程序,但由于某种原因失败了。

如果我有以下脚本:

import os;
os.system("C:\\Temp\\a b c\\Notepad.exe");
raw_input();

然后它失败并出现以下错误:

'C:\Temp\a' 不是内部或外部命令、可运行程序或批处理文件。

如果我用引号转义程序:

import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe"');
raw_input();

然后就可以了。但是,如果我添加一个参数,它会再次停止工作:

import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe" "C:\\test.txt"');
raw_input();

执行程序并等待它完成的正确方法是什么?我不需要从中读取输出,因为它是一个可视化程序,它完成一项工作然后退出,但我需要等待它完成。

另请注意,将程序移动到非空格路径也不是一种选择。


这也不起作用:

import os;
os.system("'C:\\Temp\\a b c\\Notepad.exe'");
raw_input();

注意交换的单/双引号。

这里有或没有记事本的参数,它都会失败并显示错误消息

文件名、目录名或卷标语法不正确。

【问题讨论】:

【参考方案1】:

subprocess.call 将避免必须处理各种 shell 的引用约定的问题。它接受一个列表,而不是一个字符串,因此参数更容易分隔。即

import subprocess
subprocess.call(['C:\\Temp\\a b c\\Notepad.exe', 'C:\\test.txt'])

【讨论】:

在windows中使用原始字符串要简单得多:r"C:\Temp\a b c\Notepad.exe" 是的,os.exec* 函数将替换当前进程,因此您的 python 进程将不会继续。它们在 unix 上使用得更多,其中 shell 启动命令的一般方法是 fork(),然后在子进程中 exec()。 用于此的 windows 方法是 os.spawn 系列,可以使用它来代替。虽然 subprocess 更便携,并且在控制过程(捕获输入/输出等)方面提供了更大的灵活性,因此是首选。 @PierreBdr:在某些情况下,原始字符串不起作用:您需要尾部斜杠。例如 r'c:\foo\bar\'。实际上,使用正斜杠可能会更好。这些在整个 Windows API 中都被接受(尽管并非总是被某些 shell 命令(例如复制)) 对于 python >= 3.5 subprocess.call 应该替换为 subprocess.run docs.python.org/3/library/subprocess.html#older-high-level-api【参考方案2】:

这是一种不同的做法。

如果您使用的是 Windows,则以下行为类似于在资源管理器中双击文件,或将文件名作为 DOS“启动”命令的参数:文件以任何应用程序(如果有)及其扩展名打开相关联。

filepath = 'textfile.txt'
import os
os.startfile(filepath)

例子:

import os
os.startfile('textfile.txt')

如果记事本与 .txt 文件关联,这将使用记事本打开 textfile.txt。

【讨论】:

*nix 系统是否有等效功能? @Romeno:你可以试试:webbrowser.open("textfile.txt") 它应该会打开一个文本编辑器。另见"start the second program wholly on its own, as though I just 'double-clicked on it'."【参考方案3】:

最外层的引号被 Python 自己使用,Windows shell 看不到它。如上所述,Windows 只理解双引号。 Python 将在 Windows 上将正斜杠转换为反斜杠,因此您可以使用

os.system('"C://Temp/a b c/Notepad.exe"')

' 被 Python 使用,然后将“C://Temp/a b c/Notepad.exe”(作为 Windows 路径,不需要双反斜杠)传递给 CMD.EXE

【讨论】:

这在os.system('curl URL > file') 这样的场景中似乎是最好的,我希望看到 cURL 的进度条刷新非常大的文件。 如果反斜杠后的第一个字母有特殊含义(即\t\n 等),则该特定反斜杠必须加倍。成为 Windows 路径与此无关。 请注意,如果您在 Windows 上使用 os.system(),则 cmd 窗口将打开并保持打开状态,直到您关闭它启动的进程。恕我直言,最好使用os.startfile() 别忘了import os【参考方案4】:

至少在 Windows 7 和 Python 3.1 中,如果命令路径中有空格,Windows 中的os.system 需要命令行双引号。例如:

  TheCommand = '\"\"C:\\Temp\\a b c\\Notepad.exe\"\"'
  os.system(TheCommand)

一个让我难过的真实例子是在 VirtualBox 中克隆一个驱动器。上面的subprocess.call 解决方案因为一些访问权限问题没有工作,但是当我双引号命令时,os.system 变得高兴:

  TheCommand = '\"\"C:\\Program Files\\Sun\\VirtualBox\\VBoxManage.exe\" ' \
                 + ' clonehd \"' + OrigFile + '\" \"' + NewFile + '\"\"'
  os.system(TheCommand)

【讨论】:

就是这样!我会选择subprocess,但有时os.systemos.popen(...).read() 的打字速度更快。顺便说一句,你不需要在单引号内转义双引号,即'""C:\\Temp\\a b c\\Notepad.exe""' 就可以了。【参考方案5】:

对于 python >= 3.5,应使用 subprocess.run 代替 subprocess.call

https://docs.python.org/3/library/subprocess.html#older-high-level-api

import subprocess
subprocess.run(['notepad.exe', 'test.txt'])

【讨论】:

【参考方案6】:
import win32api # if active state python is installed or install pywin32 package seperately

try: win32api.WinExec('NOTEPAD.exe') # Works seamlessly
except: pass

【讨论】:

这个方法似乎不需要引用,例如 win32api.WinExec('pythonw.exe d:\web2py\web2py.py -K welcome') 在后台启动 web2py 调度程序。 @rahul 并且除了可执行文件的参数之外吗?所以如果你想让记事本打开一个文件还是分开的?【参考方案7】:

我怀疑这与您在 Windows 中使用快捷方式时的问题相同...试试这个:

import os;
os.system("\"C:\\Temp\\a b c\\Notepad.exe\" C:\\test.txt");

【讨论】:

对不起,这也不起作用,编辑问题以反映这一点。 我认为 windows 只使用 ",而不是 ' 来引用。如果你改变它,这可能会起作用。但是,如果你嵌入了引号等,你仍然会遇到问题。 我认为两者都需要,但您可能是对的。我知道它(至少在 shell 中)用双引号起作用。 +1 这是最好的,windows XP, 2007 home edition 运行良好【参考方案8】:

假设我们要运行您的 Django Web 服务器(在 Linux 中),您的路径 (path='/home/<you>/<first-path-section> <second-path-section>') 之间有空格,请执行以下操作:

import subprocess

args = ['/manage.py'.format('/home/<you>/<first-path-section> <second-path-section>'), 'runserver']
res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()

if not error_:
    print(output)
else:
    print(error_)

[注意]:

不要忘记访问权限:chmod 755 -R &lt;'yor path'&gt; manage.py 是可执行的:chmod +x manage.py

【讨论】:

【参考方案9】:

对于 Python 3.7,请使用 subprocess.call。使用原始字符串来简化 Windows 路径:

import subprocess
subprocess.call([r'C:\Temp\Example\Notepad.exe', 'C:\test.txt'])

【讨论】:

【参考方案10】:

不需要子流程,可以简单的实现

GitPath="C:\\Program Files\\Git\\git-bash.exe"# Application File Path in mycase its GITBASH
os.startfile(GitPath)

【讨论】:

以上是关于如何从 Python 执行程序? os.system 由于路径中的空格而失败的主要内容,如果未能解决你的问题,请参考以下文章

subprocess

如何从 Python 执行程序? os.system 由于路径中的空格而失败

如何在不从终端或任何编辑器执行的情况下运行 python 程序 [重复]

如何创建一个可以直接从 shell 执行的程序(谐波和)?

Shell 脚本:从 shell 脚本中执行 python 程序

如何从一个简单的网络应用程序中注销。在 CherryPy,Python