Сообщить об ошибке.

Функция run() модуля subprocess в Python

Запустить команду/программу с аргументами из кода Python

Синтаксис:

import subprocess

subprocess.run(args, *, stdin=None, input=None, stdout=None, 
               stderr=None, capture_output=False, shell=False, 
               cwd=None, timeout=None, check=False, 
               encoding=None, errors=None, text=None, 
               env=None, universal_newlines=None)

Параметры:

Аргументы функции, за исключением обязательного args - являются не обязательны и следовательно задаются только ключевыми словами.

  • args - запускаемая программа с аргументами,
  • stdin=None - поток данных, отправляемых в процесс,
  • input=None - поток данных, отправляемых в процесс,
  • stdout=None - поток вывода программы,
  • stderr=None - поток ошибок программы,
  • capture_output=False - захват вывода stdout и stderr,
  • shell=False - используйте True, если программа и ее аргументы представлены как одна строка,
  • cwd=None - путь к рабочему каталогу запускаемой программы,
  • timeout=None - максимально-допустимое время выполнения запущенной программы,
  • check=False - вызывает исключение при завершении запущенной программы с ошибками,
  • encoding=None - кодировка, если input - строка,
  • errors=None - обработчик ошибок кодировки,
  • text=None - текстовый режим для stdin, stdout и stderr,
  • env=None - переменные среды для нового процесса,
  • universal_newlines=None - тоже, что и параметр text.

Ключевые аргументы этой функции это лишь наиболее распространенные параметры, правила использования которых описанными в разделе "Часто используемые аргументы".

Возвращаемое значение:

Описание:

Функция run() модуля subprocess запускает команду/скрипт/программу с аргументами, ждет завершения команды, а затем возвращает экземпляр CompletedProcess() с результатами работы.

Полная сигнатура функции subprocess.run() в значительной степени совпадает с сигнатурой конструктора subprocess.Popen(), a большинство аргументов этой функции передаются в интерфейс последней кроме параметров timeout, input, check и capture_output.

Если аргумент capture_output () имеет значение True, то вывод stdout и stderr будут захвачены. При использовании, внутренний объект subprocess.Popen() автоматически создается с stdout=subprocess.PIPE и stderr=subprocess.PIPE. Аргументы stdout и stderr не могут быть предоставлены одновременно с capture_output. Если необходимо захватить и объединить оба потока в один, то используйте stdout=subprocess.PIPE и stderr=subprocess.STDOUT вместо capture_output=True.

Аргумент timeout передается в subprocess.Popen.communicate(). Если тайм-аут истекает, то дочерний процесс, в котором запущена программа будет принудительно остановлен и ожидание завершения процесса прекращается. Исключение subprocess.TimeoutExpired будет повторно вызвано после завершения дочернего процесса.

Аргумент input передается в subprocess.Popen.communicate() и следовательно в стандартный поток дочернего процесса. Если он используется, то это должна быть последовательность байтов или строка - если задана кодировка encoding и errors или аргумент text имеет значение True. При использовании аргумента input, внутренний объект subprocess.Popen автоматически создается с помощью значения аргумента stdin=subprocess.PIPE при этом сам аргумент stdin может не указываться.

Если аргумент check=True и процесс завершается с ненулевым кодом выхода, то будет вызвано исключение subprocess.CalledProcessError. Атрибуты этого исключения содержат аргументы запуска программы, код ее выхода, а так же stdout и stderr, если они были захвачены.

Если указаны кодировка encoding или errors или аргумент text имеет значение True, то файловые объекты для stdin, stdout и stderr открываются в текстовом режиме с использованием указанной кодировки и обработчика ошибок или значения по умолчанию io.TextIOWrapper().

Значение аргумента universal_newlines эквивалентно аргументу text и предназначен для обратной совместимости. По умолчанию файловые объекты открываются в двоичном режиме.

Если аргумент env не равен None, то это должен быть словарь, который определяет переменные среды для нового процесса. Он используются вместо поведения по умолчанию - наследования среды текущего процесса. Аргумент env непосредственно передается в конструктор subprocess.Popen().

Примеры исполнения команд/программ из кода в Python.

>>> import subprocess
>>> result = subprocess.run(['ls', '-ls', '/tmp'])
# итого 44
# 4 drwxrwxr-x 2 docs-python docs-python 4096 мая 12 09:39  closeditems
# 0 srwx------ 1 sddm   sddm      0 мая 12 08:51  sddm-:0-gYOiIB
# 4 drwx------ 2 docs-python docs-python 4096 мая 12 09:03  ssh-SGQxwtKxNQGo
# 4 -rw------- 1 docs-python docs-python  317 мая 12 09:56  tmp-26999MFPH5MgIW157.tpl
# 4 drwx------ 2 docs-python docs-python 4096 мая 12 09:12 'VSCode Crashes'
# 4 -rw------- 1 docs-python docs-python  110 мая 12 09:03  xauth-1000-_0
# ...

Чтобы вызывать команды, в которых используются wildcard-выражения *tpl, нужно добавлять аргумент shell.

>>> import subprocess
>>> result = subprocess.run('ls -ls /tmp/*tpl', shell=True)
# 4 -rw------- 1 docs-python docs-python 317 мая 12 09:56 /tmp/tmp-26999MFPH5MgIW157.tpl
>>> result.returncode
# 0

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

>>> import subprocess
>>> result = subprocess.run('ls -ls /tmp/*tpl', shell=True, \
                            stdout=subprocess.PIPE, encoding='utf-8')
>>> result.stdout
# '4 -rw------- 1 docs-python docs-python 317 мая 12 09:56 /tmp/tmp-26999MFPH5MgIW157.tpl\n'
>>> result.returncode
# 0

Отключение вывода.

>>> import subprocess
>>> result = subprocess.run(['ls', '-ls', '/tmp/'], stdout=subprocess.DEVNULL)
>>> print(result.stdout)
# None
>>> result.returncode
# 0
>>> result.args
# ['ls', '-ls', '/tmp/']

Если команда была выполнена с ошибкой или не отработала корректно, вывод команды попадет на стандартный поток ошибок.

Получить этот вывод можно так же, как и стандартный поток вывода:

>>> import subprocess
>>> result = subprocess.run(['ping', '-c', '3', '-n', 'host.host'], \
                            stderr=subprocess.PIPE, encoding='utf-8')
>>> result.stderr
# 'ping: host.host: Неизвестное имя или служба\n'

Функция ping() проверяет доступность адреса address и возвращает stdout, если адрес доступен или stderr, если адрес недоступен.

import subprocess

def ping(address):
    reply = subprocess.run(['ping', '-c', '3', '-n', address],
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           encoding='utf-8')
    if reply.returncode == 0:
        return reply.stdout
    else:
        return reply.stderr

>>> print(ping('yandex.ru'))
# PING yandex.ru (5.255.255.5) 56(84) bytes of data.
# 64 bytes from 5.255.255.5: icmp_seq=1 ttl=249 time=20.0 ms
# 64 bytes from 5.255.255.5: icmp_seq=2 ttl=249 time=20.2 ms
# 64 bytes from 5.255.255.5: icmp_seq=3 ttl=249 time=20.2 ms
# 
# --- yandex.ru ping statistics ---
# 3 packets transmitted, 3 received, 0% packet loss, time 2002ms
# rtt min/avg/max/mdev = 20.058/20.166/20.220/0.076 ms

>>> print(ping('host.ho'))
# ping: host.ho: Неизвестное имя или служба

>>> print(ping('10.10.10.10'))
# PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data.
# 64 bytes from 10.10.10.10: icmp_seq=1 ttl=64 time=0.201 ms
# 64 bytes from 10.10.10.10: icmp_seq=2 ttl=64 time=0.212 ms
# 64 bytes from 10.10.10.10: icmp_seq=3 ttl=64 time=0.201 ms
# 
# --- 10.10.10.10 ping statistics ---
# 3 packets transmitted, 3 received, 0% packet loss, time 2027ms
# rtt min/avg/max/mdev = 0.201/0.204/0.212/0.017 ms