Как из python запустить программу
Для запуска любой внешней команды или программы под python используется os.system(«path/to/program»)
import os os.system('/usr/bin/firefox')
Выше приведенный пример здорово работает если только в пути нету пробелов (например, ‘Mozilla Firefox’).
Для того, что бы командная оболочка правильно трактовала имена с пробелами необходимо их экранировать в кавычки, например так:
import os os.system(r'c:/"Program Files"/"Mozilla Firefox"/firefox.exe')
Если не знать как правильно передать путь в os.system то можно долго провозится, ломая голову почему оно не хочет запускать программы.
Для упрощения запуска команд, в пути которых есть пробелы, существует os.startfile:
import os os.startfile(r'c:/Program Files/Mozilla Firefox/firefox.exe')
os.startfile принимает простой текст, без необходимости заключать в кавычки имена папок с пробелами.
Еще два варианта (источник), каждый хорош в своем случаи
import subprocess import shlex cmd = 'ls -al' args = shlex.split(cmd) p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) result = p.communicate()[0]
import commands commands.getoutput('ls -la')
Начиная с версии 3 и выше запуск рекомендуется производить через subprocess.
import subprocess proc = subprocess.Popen("ping -c2 %s" % ip, shell=True, stdout=subprocess.PIPE) out = proc.stdout.readlines() # или out = proc.communicate()
Как запустить приложение или вызвать системную команду в Python?
Перечислим основные способы вызова внешних программ в Питоне, включая их преимущества и недостатки.
os.system
Вызов os.system принимает команду и аргументы в shell-оболочку вашей операционной системы. Таким образом можно запускать несколько команд одновременно, настраивать каналы и перенаправление ввода/вывода. Приведем пример:
os.system("first_command < input_file | second_command >output_file")
Однако, хотя это очень удобно, вам придется вручную выполнять экранирование служебных символов в переданной строке. С другой стороны, с помощью os.system можно запускать команды, которые являются командами shell, а не только внешние приложения.
os.popen
Вызов os.popen делает то же самое, что и os.system, за исключением того, что он предоставляет вам файлоподобный объект, который вы можете использовать для доступа к стандартному вводу/выводу для этого процесса. Есть 3 разных варианта popen, которые обрабатывают ввод-вывод немного по-разному. Пример:
print(os.popen("ls -l").read())
subprocess.Popen
Класс subprocess.Popen используется в качестве замены os.popen, но имеет недостаток в том, что он немного сложнее в силу своей полноты. Пример:
print subprocess.Popen("echo Hello", shell=True, stdout=subprocess.PIPE).stdout.read() что аналогично: print os.popen("echo Hello").read()
Но удобно иметь все опции в одном унифицированном классе вместо 4-х разных функций popen.
subprocess.call
subprocess.call Используется в основном так же, как класс Popen, и принимает все те же аргументы, но он просто ожидает завершения команды и выдает код возврата. Пример:
code = subprocess.call("echo Hello", shell=True)
subprocess.run
subprocess.run Доступен только в Python 3.5+. Он аналогичен приведенному выше коду, но более гибкий и возвращает объект CompletedProcess, когда команда завершает выполнение.
os.fork , os.exec , os.spawn похожи на их аналоги на языке Си, но мы не рекомендуем использовать их напрямую.
Выполнение внешних команд в Python
Одна из распространенных проблем, с которой сталкиваются разработчики на Python — это необходимость выполнить внешнюю программу или системную команду прямо из своего кода. Примером может быть ситуация, когда требуется запустить скрипт оболочки или команду операционной системы для получения информации о системе, запуска других программ и т.д.
Python предоставляет несколько встроенных модулей и функций для работы с системными командами и выполнения внешних программ. Одним из таких модулей является модуль os .
Модуль os в Python предоставляет функции для взаимодействия с операционной системой. Функция os.system() позволяет выполнять системные команды.
import os os.system('ls')
В этом примере команда ls будет выполнена, и результат ее выполнения будет выведен на экран.
Однако, этот способ имеет свои недостатки. В частности, он не позволяет обрабатывать вывод команды как строку в Python. Для этого лучше использовать модуль subprocess .
Модуль subprocess предназначен для запуска новых приложений или программ, которые можно контролировать из своего кода. Этот модуль позволяет создавать дополнительные процессы, соединяться с их вводом/выводом/ошибками и получать их коды возврата.
import subprocess output = subprocess.run(['ls', '-l'], capture_output=True, text=True) print(output.stdout)
В этом примере мы используем функцию subprocess.run() , чтобы выполнить команду ls -l . Мы также используем два дополнительных аргумента: capture_output=True , чтобы перехватить вывод команды, и text=True , чтобы вернуть этот вывод в виде строки. Затем мы выводим результат на экран.
Таким образом, Python предоставляет удобные инструменты для выполнения внешних команд и программ прямо из кода.
Как использовать субпроцесс для запуска внешних программ в Python 3

Python 3 включает модуль subprocess для запуска внешних программ и чтения их выводов в коде Python.
Модуль subprocess может оказаться вам полезен, если вы хотите использовать на своем компьютере другую программу из вашего кода Python. Например, вы можете запустить git из своего кода Python для извлечения в ваш проект, отслеживаемый в системе управления версиями git . Поскольку с помощью модуля subprocess можно контролировать любую программу, доступную на вашем компьютере, приведенные здесь примеры применимы к любым внешним программам, которые вы можете запустить из своего кода Python.
subprocess содержит несколько классов и функций, но в этом обучающем модуле мы расскажем об одной из самых полезных функций модуля subprocess : subprocess.run . Мы изучим разные схемы его применения и основные аргументы ключевых слов.
Предварительные требования
Чтобы получить максимум знаний из этого обучающего модуля, рекомендуется иметь небольшое представление о программировании на Python 3. Дополнительную информацию можно найти в следующих обучающих руководствах:
Запуск внешней программы
Теперь вы можете использовать функцию subprocess.run для запуска внешней программы с кода Python. Прежде всего необходимо импортировать в программу модули subprocess и sys :
import subprocess import sys result = subprocess.run([sys.executable, "-c", "print('ocean')"])
Если вы запустите их, вы увидите следующий вывод:
Outputocean
Рассмотрим этот пример:
- sys.executable — абсолютный путь к исполняемому файлу Python, из которого изначально была запущена ваша программа. Например, sys.executable может быть путем, таким как /usr/local/bin/python .
- subprocess.run получает список строк, состоящих из компонентов команды, которую мы пытаемся запустить. Поскольку первой строкой мы передаем sys.executable , мы предписываем subprocess.run запустить новую программу Python.
- Компонент -c — это опция командной строки python , позволяющая передать строку с целой программой Python для исполнения. В нашем случае мы передаем программу, которая распечатывает строку ocean .
Вы можете представить каждую запись в списке, отправляемом в subprocess.run , как отделенную пробелом. Например, [sys.executable, «-c», «print(‘ocean’)»] примерно эквивалентно /usr/local/bin/python -c «print(‘ocean’)» . Обратите внимание, что subprocess автоматически заключает в кавычки компоненты команды перед их запуском в операционной системе, так что вы можете передать имя файла с пробелами.
Предупреждение. Никогда не передавайте в subprocess.run строки из ненадежных источников. Поскольку subprocess.run может выполнять на компьютере произвольные команды, злоумышленники могут использовать его для манипуляции компьютером непредвиденным образом.
Захват вывода внешней программы
Теперь мы можем вызывать внешнюю программу subprocess.run . Далее мы покажем, как захватывать вывод этой программы. Например, этот процесс может быть полезным, если бы мы хотели использовать файлы git ls для вывода всех файлов, хранящихся в системе контроля версий.
Примечание. Для примеров, показанных в этом разделе, требуется версия Python 3.7 или выше. В частности, в версию Python 3.7, выпущенную в июне 2018 г. были добавлены аргументы capture_output и ключевое слово text .
Дополним наш предыдущий пример:
import subprocess import sys result = subprocess.run( [sys.executable, "-c", "print('ocean')"], capture_output=True, text=True ) print("stdout:", result.stdout) print("stderr:", result.stderr)
Если запустить этот код, результат будет выглядеть следующим образом:
Outputstdout: ocean stderr:
Этот пример в целом аналогичен рассмотренному в первом разделе, и мы все еще запускаем субпроцесс для печати ocean . Однако теперь мы передаем аргументы ключевых слов capture_output=True и text=True в subprocess.run .
subprocess.run возвращает объект subprocess.CompletedProcess , который привязан к результату . Объект subprocess.CompletedProcess содержит детали о коде выхода внешней программы и ее выводе. Благодаря capture_output=True в result.stdout и result.stderr вносится соответствующий вывод внешней программы. По умолчанию result.stdout и result.stderr привязаны как байты, но аргумент ключевого слова text=True предписывает Python декодировать байты в строки.
В разделе вывода stdout — это ocean (плюс новая строка в конце, где print добавляет явность), и у нас нет stderr .
Рассмотрим пример, где значение stderr не пустое:
import subprocess import sys result = subprocess.run( [sys.executable, "-c", "raise ValueError('oops')"], capture_output=True, text=True ) print("stdout:", result.stdout) print("stderr:", result.stderr)
Если запустить этот код, вывод будет выглядеть следующим образом:
Outputstdout: stderr: Traceback (most recent call last): File "", line 1, in ValueError: oops
Этот код запускает субпроцесс Python, который немедленно выдает ошибку ValueError . При просмотре окончательного результата мы не видим ничего в stdout и видим результат Traceback ошибки ValueError в stderr . Это связано с тем, что по умолчанию Python записывает Traceback необработанного исключения в stderr .
Создание исключения при коде ошибки выхода
Иногда бывает полезно создать исключение, если при выходе из работающей программы выдается код ошибки выхода. Программы, выдающие нулевой код ошибки при выходе считаются успешными, однако при ненулевом коде ошибки выхода считается, что в программе произошла ошибка. Например, данная система может быть полезной, если нам нужно выдавать исключение при запуске файлов git ls в каталоге, не являющемся репозиторием git .
Мы можем использовать аргумент ключевого слова check=True , чтобы subprocess.run выдавал исключение в случае возврата внешней программой ненулевого кода ошибки выхода:
import subprocess import sys result = subprocess.run([sys.executable, "-c", "raise ValueError('oops')"], check=True)
Если запустить этот код, вывод будет выглядеть следующим образом:
OutputTraceback (most recent call last): File "", line 1, in ValueError: oops Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/subprocess.py", line 512, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command '['/usr/local/bin/python', '-c', "raise ValueError('oops')"]' returned non-zero exit status 1.
Этот вывод показывает, что мы запустили субпроцесс, выдавший ошибку, которая выводится в stderr на нашем терминале. Затем subprocess.run добросовестно выдал ошибку subprocess.CalledProcessError от нашего имени в нашей основной программе Python.
Также модуль subprocess включает метод subprocess.CompletedProcess.check_returncode , который можно использовать с похожим результатом:
import subprocess import sys result = subprocess.run([sys.executable, "-c", "raise ValueError('oops')"]) result.check_returncode()
Если мы запустим этот код, мы получим:
OutputTraceback (most recent call last): File "", line 1, in ValueError: oops Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/subprocess.py", line 444, in check_returncode raise CalledProcessError(self.returncode, self.args, self.stdout, subprocess.CalledProcessError: Command '['/usr/local/bin/python', '-c', "raise ValueError('oops')"]' returned non-zero exit status 1.
Поскольку мы не передали check=True в subprocess.run , мы успешно привязали экземпляр subprocess.CompletedProcess к результату , хотя наша программа выполнила выход с ненулевым кодом ошибки. При этом при вызове result.check_returncode() выдается ошибка subprocess.CalledProcessError , поскольку модуль обнаруживает код ошибки выхода для завершенного процесса.
Использование timeout для раннего выхода из программ
subprocess.run имеет аргумент timeout , позволяющий остановить внешнюю программу, если ее выполнение занимает слишком много времени:
import subprocess import sys result = subprocess.run([sys.executable, "-c", "import time; time.sleep(2)"], timeout=1)
Если запустить этот код, результат будет выглядеть следующим образом:
OutputTraceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/subprocess.py", line 491, in run stdout, stderr = process.communicate(input, timeout=timeout) File "/usr/local/lib/python3.8/subprocess.py", line 1024, in communicate stdout, stderr = self._communicate(input, endtime, timeout) File "/usr/local/lib/python3.8/subprocess.py", line 1892, in _communicate self.wait(timeout=self._remaining_time(endtime)) File "/usr/local/lib/python3.8/subprocess.py", line 1079, in wait return self._wait(timeout=timeout) File "/usr/local/lib/python3.8/subprocess.py", line 1796, in _wait raise TimeoutExpired(self.args, timeout) subprocess.TimeoutExpired: Command '['/usr/local/bin/python', '-c', 'import time; time.sleep(2)']' timed out after 0.9997982999999522 seconds
Субпроцесс, который мы попытались запустить, использовал функцию time.sleep для сна в течение 2 секунд. Однако мы передали аргумент с ключевым словом timeout=1 в subprocess.run , чтобы закрыть наш субпроцесс по таймауту по прошествии 1 секунды. Это объясняет, почему при вызове subprocess.run в конечном итоге было выдано исключение subprocess.TimeoutExpired .
Обратите внимание, что аргумент ключевого слова timeout для subprocess.run является приблизительным. Python постарается остановить субпроцесс после заданного в аргументе timeout количества секунд, но это не обязательно будет точным.
Передача ввода в программы
Иногда программы ожидают передачи ввода через stdin .
Аргумент ключевого слова input для subprocess.run позволяет передавать данные в stdin субпроцесса. Например:
import subprocess import sys result = subprocess.run( [sys.executable, "-c", "import sys; print(sys.stdin.read())"], input=b"underwater" )
Запустив этот код, мы получим примерно следующий вывод:
Outputunderwater
В данном случае мы передали байты underwater в input . Наш целевой субпроцесс использовал sys.stdin для чтения переданного в stdin аргумента ( underwater ) и вывел его в результатах.
Аргумент ключевого слова input может быть полезен, если вы хотите создать цепочку из нескольких вызовов subprocess.run с передачей вывода одной программы как ввода в другую программу.
Заключение
Модуль subprocess — это мощный компонент стандартной библиотеки Python, позволяющий легко запускать внешние программы и просматривать их вывод. В этом обучающем модуле вы научились использовать subprocess.run для управления внешними программами, передачи ввода в эти программы, анализа их вывода и проверки возвращаемых ими кодов.
Модуль subprocess представляет дополнительные классы и утилиты, которые мы не охватили в этом обучающем модуле. Изучив основы, вы можете использовать документацию модуля subprocess для получения дополнительной информации о других имеющихся классах и утилитах.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
