标签归档:shellexecute

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

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

我有一个需要执行外部程序的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();

注意交换的单/双引号。

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

文件名,目录名称或卷标签语法不正确。

I have a Python script that needs to execute an external program, but for some reason fails.

If I have the following script:

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

Then it fails with the following error:

‘C:\Temp\a’ is not recognized as an internal or external command, operable program or batch file.

If I escape the program with quotes:

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

Then it works. However, if I add a parameter, it stops working again:

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

What is the right way to execute a program and wait for it to complete? I do not need to read output from it, as it is a visual program that does a job and then just exits, but I need to wait for it to complete.

Also note, moving the program to a non-spaced path is not an option either.


This does not work either:

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

Note the swapped single/double quotes.

With or without a parameter to Notepad here, it fails with the error message

The filename, directory name, or volume label syntax is incorrect.


回答 0

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

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

subprocess.call will avoid problems with having to deal with quoting conventions of various shells. It accepts a list, rather than a string, so arguments are more easily delimited. i.e.

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

回答 1

这是另一种方式。

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

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

例:

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

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

Here’s a different way of doing it.

If you’re using Windows the following acts like double-clicking the file in Explorer, or giving the file name as an argument to the DOS “start” command: the file is opened with whatever application (if any) its extension is associated with.

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

Example:

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

This will open textfile.txt with Notepad if Notepad is associated with .txt files.


回答 2

最外面的引号由Python本身使用,Windows Shell看不到它。如上所述,Windows仅能理解双引号。Python将在Windows上将正斜杠转换为反斜杠,因此您可以使用

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

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

The outermost quotes are consumed by Python itself, and the Windows shell doesn’t see it. As mentioned above, Windows only understands double-quotes. Python will convert forward-slashed to backslashes on Windows, so you can use

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

The ‘ is consumed by Python, which then passes “C://Temp/a b c/Notepad.exe” (as a Windows path, no double-backslashes needed) to CMD.EXE


回答 3

至少在Windows 7和Python 3.1中,如果命令路径中有空格,则os.systemWindows希望在命令行中双引号。例如:

  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)

At least in Windows 7 and Python 3.1, os.system in Windows wants the command line double-quoted if there are spaces in path to the command. For example:

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

A real-world example that was stumping me was cloning a drive in VirtualBox. The subprocess.call solution above didn’t work because of some access rights issue, but when I double-quoted the command, os.system became happy:

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

回答 4

import win32api # if active state python is installed or install pywin32 package seperately

try: win32api.WinExec('NOTEPAD.exe') # Works seamlessly
except: pass
import win32api # if active state python is installed or install pywin32 package seperately

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

回答 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'])

For python >= 3.5 subprocess.run should be used in place of subprocess.call

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

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

回答 6

我怀疑这与您在Windows中使用快捷方式时存在同样的问题…请尝试以下操作:

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

I suspect it’s the same problem as when you use shortcuts in Windows… Try this:

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

回答 7

假设我们要运行您的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 <'yor path'>
  • manage.py 可以辩解: chmod +x manage.py

Suppose we want to run your Django web server (in Linux) that there is space between your path (path='/home/<you>/<first-path-section> <second-path-section>'), so do the following:

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_)

[Note]:

  • Do not forget accessing permission: chmod 755 -R <'yor path'>
  • manage.py is exceutable: chmod +x manage.py

回答 8

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

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

For Python 3.7, use subprocess.call. Use raw string to simplify the Windows paths:

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

回答 9

无需子流程,可以通过以下方式轻松实现

GitPath =“ C:\ Program Files \ Git \ git-bash.exe”#在mycase中,其GITBASH os.startfile(GitPath)中的应用程序文件路径

No need for sub-process, It can be simply achieved by

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