Как мне запустить программу из 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();

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

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

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

8 ответов

Решение

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

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

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

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

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

Пример:

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

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

Внешние кавычки потребляются самим 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

По крайней мере, в 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)

Для питона>= 3,5 subprocess.run следует использовать вместо subprocess.call

https://docs.python.org/3/library/subprocess.html

import subprocess
subprocess.run(['notepad.exe', 'test.txt'])
import win32api # if active state python is installed or install pywin32 package seperately

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

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

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

Для Python 3.7 используйте subprocess.call. Используйте необработанную строку, чтобы упростить пути Windows:

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

Предположим, мы хотим запустить ваш веб-сервер 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

Нет необходимости в подпроцессе, это может быть просто достигнуто

GitPath="C:\Program Files\Git\git-bash.exe"# Путь к файлу приложения в моем случае это GITBASH os.startfile(GitPath)

Другие вопросы по тегам