Как мне запустить программу из Python? Сбой os.system из-за пробелов в пути - PullRequest
248 голосов
/ 15 октября 2008

У меня есть скрипт 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();

Обратите внимание на замененные одинарные / двойные кавычки.

С параметром Notepad или без него здесь происходит сбой с сообщением об ошибке

Неверный синтаксис имени файла, имени каталога или метки тома.

Ответы [ 8 ]

275 голосов
/ 15 октября 2008

subprocess.call позволит избежать проблем, связанных с соглашениями о цитировании различных оболочек. Он принимает список, а не строку, поэтому аргументы легче разделить. т.е.

import subprocess
subprocess.call(['C:\\Temp\\a b c\\Notepad.exe', 'C:\\test.txt'])
62 голосов
/ 16 октября 2008

Вот другой способ сделать это.

Если вы используете Windows, следующие действия аналогичны двойному щелчку файла в Проводнике или присвоению имени файла в качестве аргумента команде «start» DOS: файл открывается любым приложением (если есть) с его расширением ассоциируется с.

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

Пример:

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

Откроется textfile.txt с помощью Блокнота, если Блокнот связан с файлами .txt.

34 голосов
/ 26 мая 2009

Самые внешние кавычки потребляются самим Python, а оболочка Windows не видит его. Как упоминалось выше, Windows понимает только двойные кавычки. Python преобразует косую черту в обратную косую черту в Windows, поэтому вы можете использовать

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

'потребляется Python, который затем передает "C: // Temp / a b c / Notepad.exe" (как путь Windows, двойная обратная косая черта не требуется) в CMD.EXE

18 голосов
/ 26 октября 2009

По крайней мере, в Windows 7 и Python 3.1, os.system в Windows требует командной строки в двойных кавычках , если в пути к команде есть пробелы. Например:

  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)
7 голосов
/ 30 апреля 2010
import win32api # if active state python is installed or install pywin32 package seperately

try: win32api.WinExec('NOTEPAD.exe') # Works seamlessly
except: pass
4 голосов
/ 15 октября 2008

Я подозреваю, что это та же проблема, что и при использовании ярлыков в Windows ... Попробуйте это:

import os;
os.system("\"C:\\Temp\\a b c\\Notepad.exe\" C:\\test.txt");
3 голосов
/ 22 января 2018

Для 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'])
0 голосов
/ 22 января 2018

Предположим, мы хотим запустить ваш веб-сервер Django (в Linux), чтобы между вашим путем было свободное пространство (путь = '/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
...