subprocess — Управление подпроцессами

Исходный код: Lib/subprocess.py.


Модуль subprocess позволяет порождать новые процессы, подключаться к их трубам ввода/вывода/ошибок и получать их коды возврата. Этот модуль призван заменить несколько старых модулей и функций:

os.system
os.spawn*

Информация о том, как модуль subprocess может быть использован для замены этих модулей и функций, приведена в следующих разделах.

См.также

PEP 324 – PEP, предлагающий модуль подпроцесса

Использование модуля subprocess

Рекомендуемый подход к вызову подпроцессов заключается в использовании функции run() для всех случаев использования, которые она может обработать. Для более сложных случаев можно использовать непосредственно базовый интерфейс Popen.

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, **other_popen_kwargs)

Выполнить команду, описанную args. Дождитесь завершения команды, затем верните экземпляр CompletedProcess.

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

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

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

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

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

Если указаны encoding или errors, или text равно true, файловые объекты для stdin, stdout и stderr открываются в текстовом режиме с использованием указанных encoding и errors или io.TextIOWrapper по умолчанию. Аргумент universal_newlines эквивалентен text и предоставляется для обратной совместимости. По умолчанию файловые объекты открываются в двоичном режиме.

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

Примеры:

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

>>> subprocess.run(["ls", "-l", "/dev/null"], capture_output=True)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n', stderr=b'')

Добавлено в версии 3.5.

Изменено в версии 3.6: Добавлены параметры encoding и errors.

Изменено в версии 3.7: Добавлен параметр text, как более понятный псевдоним universal_newlines. Добавлен параметр capture_output.

class subprocess.CompletedProcess

Возвращаемое значение из run(), представляющее процесс, который завершился.

args

Аргументы, используемые для запуска процесса. Это может быть список или строка.

returncode

Статус завершения дочернего процесса. Как правило, статус выхода 0 означает, что процесс успешно завершился.

Отрицательное значение -N указывает на то, что дочерняя программа была завершена сигналом N (только для POSIX).

stdout

Захваченный stdout дочернего процесса. Последовательность байтов или строка, если run() был вызван с кодировкой, ошибками или text=True. None, если stdout не был перехвачен.

Если вы запустили процесс с stderr=subprocess.STDOUT, stdout и stderr будут объединены в этом атрибуте, а stderr станет None.

stderr

Захваченный stderr из дочернего процесса. Последовательность байтов или строка, если run() был вызван с кодировкой, ошибками или text=True. None, если stderr не был перехвачен.

check_returncode()

Если returncode ненулевое, вызовите сообщение CalledProcessError.

Добавлено в версии 3.5.

subprocess.DEVNULL

Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr в Popen и указывает, что будет использоваться специальный файл os.devnull.

Добавлено в версии 3.3.

subprocess.PIPE

Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr в Popen и указывает на то, что должен быть открыт канал к стандартному потоку. Наиболее полезно при использовании Popen.communicate().

subprocess.STDOUT

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

exception subprocess.SubprocessError

Базовый класс для всех остальных исключений из этого модуля.

Добавлено в версии 3.3.

exception subprocess.TimeoutExpired

Подкласс SubprocessError, поднимается, когда истекает тайм-аут при ожидании дочернего процесса.

cmd

Команда, которая была использована для порождения дочернего процесса.

timeout

Тайм-аут в секундах.

output

Выход дочернего процесса, если он был захвачен run() или check_output(). В противном случае None.

stdout

Псевдоним для вывода, для симметрии с stderr.

stderr

Вывод Stderr дочернего процесса, если он был перехвачен командой run(). В противном случае None.

Добавлено в версии 3.3.

Изменено в версии 3.5: Добавлены атрибуты stdout и stderr

exception subprocess.CalledProcessError

Подкласс SubprocessError, поднимается, когда процесс, запущенный check_call(), check_output() или run()check=True) возвращает ненулевой статус выхода.

returncode

Статус завершения дочернего процесса. Если процесс завершился из-за сигнала, это будет отрицательный номер сигнала.

cmd

Команда, которая была использована для порождения дочернего процесса.

output

Выход дочернего процесса, если он был захвачен run() или check_output(). В противном случае None.

stdout

Псевдоним для вывода, для симметрии с stderr.

stderr

Вывод Stderr дочернего процесса, если он был перехвачен командой run(). В противном случае None.

Изменено в версии 3.5: Добавлены атрибуты stdout и stderr

Часто используемые аргументы

Для поддержки широкого разнообразия случаев использования конструктор Popen (и вспомогательные функции) принимает большое количество необязательных аргументов. Для большинства типичных случаев использования многие из этих аргументов можно оставить в значениях по умолчанию. Наиболее часто требуемыми аргументами являются:

args требуется для всех вызовов и должен быть строкой или последовательностью аргументов программы. Предоставление последовательности аргументов обычно предпочтительнее, поскольку это позволяет модулю позаботиться о любом требуемом экранировании и кавычках аргументов (например, чтобы разрешить пробелы в именах файлов). Если передается одна строка, то либо shell должен быть True (см. ниже), либо строка должна просто называть программу, которая будет выполняться, без указания каких-либо аргументов.

stdin, stdout и stderr указывают стандартный вход, стандартный выход и стандартные ручки файлов ошибок выполняемой программы, соответственно. Допустимыми значениями являются PIPE, DEVNULL, существующий дескриптор файла (целое положительное число), существующий объект файла с допустимым дескриптором файла и None. PIPE указывает, что должен быть создан новый канал к дочернему файлу. DEVNULL указывает, что будет использоваться специальный файл os.devnull. При настройках по умолчанию None никакого перенаправления не произойдет; файловые хэндлы дочернего файла будут унаследованы от родительского. Кроме того, stderr может быть STDOUT, что указывает на то, что данные stderr дочернего процесса должны быть захвачены в тот же файловый хэндл, что и для stdout.

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

Для stdin символы окончания строки '\n' во входных данных будут преобразованы в стандартный разделитель строк os.linesep. Для stdout и stderr все символы окончания строки в выводе будут преобразованы в '\n'. Для получения дополнительной информации смотрите документацию класса io.TextIOWrapper, когда аргумент newline в его конструкторе равен None.

Если текстовый режим не используется, stdin, stdout и stderr будут открыты как двоичные потоки. Никакого кодирования или преобразования конца строки не выполняется.

Добавлено в версии 3.6: Добавлены параметры encoding и errors.

Добавлено в версии 3.7: Добавлен параметр text в качестве псевдонима для universal_newlines.

Примечание

Атрибут newlines файловых объектов Popen.stdin, Popen.stdout и Popen.stderr не обновляется методом Popen.communicate().

Если shell равно True, то указанная команда будет выполнена через оболочку. Это может быть полезно, если вы используете Python в основном для расширенного потока управления, который он предлагает по сравнению с большинством системных оболочек, но при этом хотите иметь удобный доступ к другим возможностям оболочки, таким как shell pipes, подстановочные знаки имен файлов, расширение переменных окружения и расширение ~ до домашнего каталога пользователя. Однако обратите внимание, что Python сам предлагает реализацию многих shell-подобных функций (в частности, glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser() и shutil).

Изменено в версии 3.3: Когда universal_newlines имеет значение True, класс использует кодировку locale.getpreferredencoding(False) вместо locale.getpreferredencoding(). Дополнительную информацию об этом изменении см. в классе io.TextIOWrapper.

Примечание

Прочитайте раздел Security Considerations перед использованием shell=True.

Эти опции, а также все остальные опции более подробно описаны в документации конструктора Popen.

Popen Constructor

Создание и управление процессами в этом модуле осуществляется с помощью класса Popen. Он предлагает большую гибкость, чтобы разработчики могли обрабатывать менее распространенные случаи, не охваченные удобными функциями.

class subprocess.Popen(args, bufsize=- 1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, extra_groups=None, user=None, umask=- 1, encoding=None, errors=None, text=None, pipesize=- 1)

Выполнение дочерней программы в новом процессе. На POSIX класс использует os.execvpe()-подобное поведение для выполнения дочерней программы. В Windows класс использует функцию Windows CreateProcess(). Аргументы для Popen следующие.

args должна быть последовательностью аргументов программы, иначе одной строкой или path-like object. По умолчанию, программа для выполнения является первым элементом в args, если args - последовательность. Если args является строкой, интерпретация зависит от платформы и описана ниже. Дополнительные отличия от поведения по умолчанию см. в аргументах shell и executable. Если не указано иное, рекомендуется передавать args в виде последовательности.

Предупреждение

Для максимальной надежности используйте полный путь к исполняемому файлу. Для поиска неквалифицированного имени на PATH используйте shutil.which(). На всех платформах передача sys.executable является рекомендуемым способом повторного запуска текущего интерпретатора Python, а для запуска установленного модуля используйте формат командной строки -m.

Разрешение пути executable (или первого элемента args) зависит от платформы. Для POSIX смотрите os.execvpe(), и обратите внимание, что при разрешении или поиске пути исполняемого файла cwd переопределяет текущий рабочий каталог, а env может переопределять переменную окружения PATH. Для Windows смотрите документацию по параметрам lpApplicationName и lpCommandLine WinAPI CreateProcess, и обратите внимание, что при разрешении или поиске исполняемого пути с помощью shell=False, cwd не переопределяет текущий рабочий каталог, а env не может переопределить переменную окружения PATH. Использование полного пути позволяет избежать всех этих вариаций.

Примером передачи некоторых аргументов внешней программе в виде последовательности является:

Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])

В POSIX, если args является строкой, то строка интерпретируется как имя или путь программы для выполнения. Однако это можно сделать, только если не передавать аргументы программе.

Примечание

Может быть неочевидно, как разбить команду оболочки на последовательность аргументов, особенно в сложных случаях. shlex.split() может проиллюстрировать, как определить правильную токенизацию для args:

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

Обратите внимание, что опции (например, -input) и аргументы (например, eggs.txt), которые в оболочке разделяются пробелами, идут в отдельных элементах списка, в то время как аргументы, которые требуют кавычек или экранирования обратного слеша при использовании в оболочке (например, имена файлов, содержащие пробелы, или команда echo, показанная выше), идут в отдельных элементах списка.

В Windows, если args является последовательностью, она будет преобразована в строку способом, описанным в Преобразование последовательности аргументов в строку в Windows. Это связано с тем, что базовый CreateProcess() оперирует строками.

Изменено в версии 3.6: Параметр args принимает значение path-like object, если shell - False, и последовательность, содержащую объекты, подобные путям на POSIX.

Изменено в версии 3.8: Параметр args принимает значение path-like object, если shell - False, и последовательность, содержащую байты и объекты, похожие на пути, в Windows.

Аргумент shell (по умолчанию False) определяет, использовать ли оболочку в качестве программы для выполнения. Если shell имеет значение True, рекомендуется передавать args как строку, а не как последовательность.

На POSIX с shell=True оболочка по умолчанию имеет значение /bin/sh. Если args является строкой, то строка определяет команду для выполнения через оболочку. Это означает, что строка должна быть отформатирована точно так же, как она была бы набрана в приглашении оболочки. Это включает, например, кавычки или обратную косую черту в именах файлов, содержащих пробелы. Если args является последовательностью, то первый элемент определяет командную строку, а все дополнительные элементы будут рассматриваться как дополнительные аргументы самой оболочки. Иными словами, Popen делает эквивалент:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

В Windows с shell=True переменная окружения COMSPEC определяет оболочку по умолчанию. Единственный раз, когда вам нужно указать shell=True в Windows, это когда команда, которую вы хотите выполнить, встроена в оболочку (например, dir или copy). Вам не нужно указывать shell=True для запуска пакетного файла или исполняемого файла на базе консоли.

Примечание

Прочитайте раздел Security Considerations перед использованием shell=True.

bufsize будет предоставлен в качестве соответствующего аргумента функции open() при создании объектов трубных файлов stdin/stdout/stderr:

  • 0 означает небуферизованный (чтение и запись являются одним системным вызовом и могут возвращать короткие значения)

  • 1 означает буферизацию строки (используется только при universal_newlines=True, т.е. в текстовом режиме)

  • любое другое положительное значение означает использование буфера приблизительно такого размера

  • отрицательный bufsize (по умолчанию) означает, что будет использоваться системное значение по умолчанию io.DEFAULT_BUFFER_SIZE.

Изменено в версии 3.3.1: bufsize теперь имеет значение по умолчанию -1, чтобы включить буферизацию по умолчанию, что соответствует поведению, ожидаемому большинством кода. В версиях до Python 3.2.4 и 3.3.1 по умолчанию неверно задавалось значение 0, которое было без буферизации и позволяло короткие чтения. Это было непреднамеренно и не соответствовало поведению Python 2, ожидаемому большинством кода.

Аргумент исполняемый указывает заменяющую программу для выполнения. Он требуется очень редко. Когда shell=False, executable заменяет программу для выполнения, указанную args. Однако исходный args все еще передается программе. Большинство программ рассматривают программу, указанную args, как имя команды, которое может отличаться от фактически выполняемой программы. В POSIX имя args становится отображаемым именем исполняемого файла в таких утилитах, как ps. Если shell=True, то на POSIX аргумент executable указывает оболочку, заменяющую оболочку по умолчанию /bin/sh.

Изменено в версии 3.6: Параметр executable принимает path-like object на POSIX.

Изменено в версии 3.8: Параметр executable принимает байт и path-like object в Windows.

stdin, stdout и stderr указывают стандартный вход, стандартный выход и стандартные ручки файлов ошибок выполняемой программы, соответственно. Допустимыми значениями являются PIPE, DEVNULL, существующий дескриптор файла (целое положительное число), существующий file object с действительным дескриптором файла и None. PIPE указывает, что должен быть создан новый канал к дочернему файлу. DEVNULL указывает, что будет использоваться специальный файл os.devnull. При настройках по умолчанию None никакого перенаправления не произойдет; файловые хэндлы дочернего файла будут унаследованы от родительского. Кроме того, stderr может быть STDOUT, что указывает на то, что данные stderr от приложений должны быть захвачены в тот же файловый хэндл, что и для stdout.

Если preexec_fn установлен на вызываемый объект, этот объект будет вызван в дочернем процессе непосредственно перед выполнением дочернего процесса. (Только POSIX)

Предупреждение

Параметр preexec_fn небезопасно использовать при наличии потоков в вашем приложении. Дочерний процесс может зайти в тупик до вызова exec. Если вы должны использовать этот параметр, сделайте его тривиальным! Сведите к минимуму количество библиотек, к которым вы обращаетесь.

Примечание

Если вам нужно изменить окружение дочерней программы, используйте параметр env, а не делайте это в preexec_fn. Параметр start_new_session может заменить ранее распространенное использование preexec_fn для вызова os.setsid() в дочерней программе.

Изменено в версии 3.8: Параметр preexec_fn больше не поддерживается в подынтерпретаторах. Использование параметра в подынтерпретаторе вызывает ошибку RuntimeError. Новое ограничение может повлиять на приложения, развернутые в mod_wsgi, uWSGI и других встроенных средах.

Если close_fds равно true, все файловые дескрипторы, кроме 0, 1 и 2, будут закрыты до выполнения дочернего процесса. В противном случае, когда close_fds равно false, файловые дескрипторы подчиняются своему наследуемому флагу, как описано в Наследование файловых дескрипторов.

В Windows, если close_fds равно true, то никакие дескрипторы не будут наследоваться дочерним процессом, если они явно не переданы в элементе handle_list STARTUPINFO.lpAttributeList или стандартным перенаправлением дескрипторов.

Изменено в версии 3.2: Значение по умолчанию для close_fds было изменено с False на то, что описано выше.

Изменено в версии 3.7: В Windows значение по умолчанию для close_fds было изменено с False на True при перенаправлении стандартных дескрипторов. Теперь можно установить close_fds на True при перенаправлении стандартных дескрипторов.

pass_fds - это необязательная последовательность дескрипторов файлов, которые должны быть открыты между родительским и дочерним файлами. Предоставление любого pass_fds заставляет close_fds быть True. (только для POSIX)

Изменено в версии 3.2: Был добавлен параметр pass_fds.

Если cwd не None, функция изменяет рабочий каталог на cwd перед выполнением дочерней функции. cwd может быть строкой, байтом или объектом path-like. На POSIX функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу является относительным.

Изменено в версии 3.6: Параметр cwd принимает path-like object на POSIX.

Изменено в версии 3.7: Параметр cwd принимает значение path-like object в Windows.

Изменено в версии 3.8: Параметр cwd принимает байтовый объект в Windows.

Если restore_signals равно true (по умолчанию), все сигналы, которые Python установил в SIG_IGN, восстанавливаются в SIG_DFL в дочернем процессе перед выполнением. В настоящее время это включает сигналы SIGPIPE, SIGXFZ и SIGXFSZ. (Только для POSIX)

Изменено в версии 3.2: Было добавлено restore_signals.

Если start_new_session равен true, то системный вызов setsid() будет выполнен в дочернем процессе до выполнения подпроцесса. (Только POSIX)

Изменено в версии 3.2: Было добавлено start_new_session.

Если group не является None, то системный вызов setregid() будет выполнен в дочернем процессе до выполнения подпроцесса. Если предоставленное значение является строкой, оно будет просмотрено через grp.getgrnam() и будет использовано значение в gr_gid. Если значение является целым числом, оно будет передано дословно. (Только для POSIX)

Availability: POSIX

Добавлено в версии 3.9.

Если extra_groups не None, то системный вызов setgroups() будет выполнен в дочернем процессе до выполнения подпроцесса. Строки, указанные в extra_groups, будут просмотрены через grp.getgrnam() и будут использованы значения в gr_gid. Целочисленные значения будут переданы дословно. (Только для POSIX)

Availability: POSIX

Добавлено в версии 3.9.

Если user не None, то системный вызов setreuid() будет выполнен в дочернем процессе до выполнения подпроцесса. Если предоставленное значение является строкой, оно будет просмотрено через pwd.getpwnam() и будет использовано значение в pw_uid. Если значение является целым числом, оно будет передано дословно. (Только для POSIX)

Availability: POSIX

Добавлено в версии 3.9.

Если umask не отрицателен, системный вызов umask() будет выполнен в дочернем процессе до выполнения подпроцесса.

Availability: POSIX

Добавлено в версии 3.9.

Если env не None, это должно быть отображение, определяющее переменные окружения для нового процесса; они используются вместо стандартного поведения наследования окружения текущего процесса.

Примечание

Если указано, env должно содержать любые переменные, необходимые для выполнения программы. В Windows для запуска side-by-side assembly указанные env должны включать действительные SystemRoot.

Если указаны encoding или errors, или text равно true, то файловые объекты stdin, stdout и stderr открываются в текстовом режиме с указанной кодировкой и errors, как описано выше в Часто используемые аргументы. Аргумент universal_newlines эквивалентен text и предоставляется для обратной совместимости. По умолчанию файловые объекты открываются в двоичном режиме.

Добавлено в версии 3.6: Были добавлены кодирование и ошибки.

Добавлено в версии 3.7: text был добавлен как более читабельный псевдоним для universal_newlines.

Если задано, то startupinfo будет объектом STARTUPINFO, который передается в базовую функцию CreateProcess. creationflags, если задан, может быть одним или несколькими из следующих флагов:

pipesize можно использовать для изменения размера трубы, когда PIPE используется для stdin, stdout или stderr. Размер трубы изменяется только на платформах, которые поддерживают это (на данный момент только Linux). Другие платформы будут игнорировать этот параметр.

Добавлено в версии 3.10: Был добавлен параметр pipesize.

Объекты Popen поддерживаются в качестве менеджеров контекста через оператор with: при выходе стандартные дескрипторы файлов закрываются, а процесс ожидает.

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

Поднимает auditing event subprocess.Popen с аргументами executable, args, cwd, env.

Изменено в версии 3.2: Добавлена поддержка контекстного менеджера.

Изменено в версии 3.6: Деструктор Popen теперь выдает предупреждение ResourceWarning, если дочерний процесс все еще запущен.

Изменено в версии 3.8: Popen может использовать os.posix_spawn() в некоторых случаях для повышения производительности. В Windows Subsystem for Linux и QEMU User Emulation конструктор Popen, использующий os.posix_spawn(), больше не вызывает исключение при ошибках типа отсутствующей программы, но дочерний процесс завершается с ненулевым returncode.

Исключения

Исключения, возникшие в дочернем процессе до того, как новая программа начала выполняться, будут повторно вызваны в родительском процессе.

Наиболее часто встречающееся исключение - OSError. Оно возникает, например, при попытке выполнить несуществующий файл. Приложения должны быть готовы к исключениям OSError. Обратите внимание, что при shell=True, OSError будет вызвано дочерней оболочкой только в том случае, если сама выбранная оболочка не была найдена. Чтобы определить, не удалось ли оболочке найти запрашиваемое приложение, необходимо проверить код возврата или вывод из подпроцесса.

Если ValueError будет вызван с недопустимыми аргументами, то возникнет ошибка Popen.

check_call() и check_output() будут поднимать CalledProcessError, если вызванный процесс вернет ненулевой код возврата.

Все функции и методы, принимающие параметр timeout, такие как call() и Popen.communicate(), будут вызывать ошибку TimeoutExpired, если таймаут истечет до завершения процесса.

Все исключения, определенные в этом модуле, наследуются от SubprocessError.

Добавлено в версии 3.3: Добавлен базовый класс SubprocessError.

Соображения безопасности

В отличие от некоторых других функций popen, эта реализация никогда не будет неявно вызывать системную оболочку. Это означает, что все символы, включая метасимволы оболочки, могут безопасно передаваться дочерним процессам. Если оболочка вызывается явно, через shell=True, приложение несет ответственность за то, чтобы все пробельные символы и метасимволы были заключены в кавычки, чтобы избежать уязвимостей shell injection. При some platforms можно использовать shlex.quote() для такой экранировки.

Объекты Попена

Экземпляры класса Popen имеют следующие методы:

Popen.poll()

Проверьте, завершился ли дочерний процесс. Установите и верните атрибут returncode. В противном случае возвращается None.

Popen.wait(timeout=None)

Дождитесь завершения дочернего процесса. Установите и верните атрибут returncode.

Если процесс не завершается по истечении timeout секунд, вызовите исключение TimeoutExpired. Безопасно перехватить это исключение и повторить ожидание.

Примечание

Это приведет к тупику, если при использовании stdout=PIPE или stderr=PIPE дочерний процесс генерирует достаточно вывода на трубу, чтобы заблокировать его в ожидании, пока буфер трубы ОС примет больше данных. Используйте Popen.communicate() при использовании труб, чтобы избежать этого.

Примечание

Функция реализована с использованием занятого цикла (неблокирующий вызов и короткое ожидание). Для асинхронного ожидания используйте модуль asyncio: см. asyncio.create_subprocess_exec.

Изменено в версии 3.3: Был добавлен таймаут.

Popen.communicate(input=None, timeout=None)

Взаимодействовать с процессом: Отправить данные в stdin. Считать данные из stdout и stderr, пока не будет достигнут конец файла. Дождаться завершения процесса и установить атрибут returncode. Необязательным аргументом input должны быть данные, которые будут отправлены дочернему процессу, или None, если данные не должны быть отправлены дочернему процессу. Если потоки были открыты в текстовом режиме, input должен быть строкой. В противном случае, это должны быть байты.

communicate() возвращает кортеж (stdout_data, stderr_data). Данные будут строками, если потоки были открыты в текстовом режиме; в противном случае - байтами.

Обратите внимание, что если вы хотите отправить данные на stdin процесса, вам нужно создать объект Popen с stdin=PIPE. Аналогично, чтобы получить в кортеже результатов что-либо кроме None, необходимо также передать stdout=PIPE и/или stderr=PIPE.

Если процесс не завершится через timeout секунд, будет вызвано исключение TimeoutExpired. Перехват этого исключения и повторная попытка обмена данными не приведет к потере вывода.

Дочерний процесс не убивается, если истекает тайм-аут, поэтому для правильной очистки хорошо работающее приложение должно убить дочерний процесс и завершить коммуникацию:

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

Примечание

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

Изменено в версии 3.3: Был добавлен таймаут.

Popen.send_signal(signal)

Посылает сигнал сигнал ребенку.

Ничего не делать, если процесс завершен.

Примечание

В Windows SIGTERM является псевдонимом для terminate(). CTRL_C_EVENT и CTRL_BREAK_EVENT могут быть посланы процессам, запущенным с параметром creationflags, который включает CREATE_NEW_PROCESS_GROUP.

Popen.terminate()

Остановить ребенка. В операционных системах POSIX метод посылает SIGTERM дочерней программе. В Windows для остановки дочерней программы вызывается функция Win32 API TerminateProcess().

Popen.kill()

Убивает ребенка. В ОС POSIX функция посылает SIGKILL ребенку. В Windows kill() является псевдонимом для terminate().

Также доступны следующие атрибуты:

Popen.args

Аргумент args в том виде, в котором он был передан в Popen – последовательность аргументов программы или иначе одна строка.

Добавлено в версии 3.3.

Popen.stdin

Если аргумент stdin был PIPE, то этот атрибут представляет собой объект потока с возможностью записи, возвращаемый командой open(). Если были указаны аргументы encoding или errors или аргумент universal_newlines был True, то поток является текстовым потоком, иначе - байтовым потоком. Если аргумент stdin не был PIPE, то этот атрибут будет None.

Popen.stdout

Если аргумент stdout был PIPE, то этот атрибут представляет собой объект потока для чтения, возвращенный командой open(). Чтение из потока обеспечивает вывод данных из дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines был True, то поток является текстовым потоком, иначе - байтовым потоком. Если аргумент stdout не был PIPE, то этот атрибут будет None.

Popen.stderr

Если аргумент stderr был PIPE, то этот атрибут представляет собой объект потока для чтения, возвращаемый командой open(). Чтение из потока обеспечивает вывод ошибок из дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines был True, то поток является текстовым потоком, иначе - байтовым потоком. Если аргумент stderr не был PIPE, то этот атрибут будет None.

Предупреждение

Используйте communicate(), а не .stdin.write, .stdout.read или .stderr.read, чтобы избежать тупиковых ситуаций из-за того, что любой из буферов труб ОС заполняется и блокирует дочерний процесс.

Popen.pid

Идентификатор процесса дочернего процесса.

Обратите внимание, что если вы установите аргумент shell в True, то это будет идентификатор процесса порожденной оболочки.

Popen.returncode

Код возврата дочернего процесса, задаваемый poll() и wait() (и косвенно communicate()). Значение None указывает на то, что процесс еще не завершился.

Отрицательное значение -N указывает на то, что дочерняя программа была завершена сигналом N (только для POSIX).

Помощники Windows Popen

Класс STARTUPINFO и следующие константы доступны только в Windows.

class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)

Для создания STARTUPINFO используется частичная поддержка структуры Windows :class:`Popen`_. Следующие атрибуты могут быть установлены путем передачи их в качестве аргументов, содержащих только ключевые слова.

Изменено в версии 3.7: Добавлена поддержка аргументов только для ключевых слов.

dwFlags

Битовое поле, определяющее, используются ли определенные атрибуты STARTUPINFO при создании окна.

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
hStdInput

Если dwFlags указывает STARTF_USESTDHANDLES, то этот атрибут является дескриптором стандартного ввода для процесса. Если STARTF_USESTDHANDLES не указан, то по умолчанию для стандартного ввода используется буфер клавиатуры.

hStdOutput

Если dwFlags указывает STARTF_USESTDHANDLES, то этот атрибут является дескриптором стандартного вывода для процесса. В противном случае этот атрибут игнорируется, и по умолчанию для стандартного вывода используется буфер окна консоли.

hStdError

Если dwFlags указывает STARTF_USESTDHANDLES, то этот атрибут является обработчиком стандартной ошибки для процесса. В противном случае этот атрибут игнорируется, и по умолчанию для стандартной ошибки используется буфер окна консоли.

wShowWindow

Если dwFlags указывает STARTF_USESHOWWINDOW, этот атрибут может быть любым из значений, которые могут быть указаны в параметре nCmdShow для функции ShowWindow, кроме SW_SHOWDEFAULT. В противном случае этот атрибут игнорируется.

Для этого атрибута предусмотрено SW_HIDE. Он используется, когда Popen вызывается вместе с shell=True.

lpAttributeList

Словарь дополнительных атрибутов для создания процесса, заданных в STARTUPINFOEX, см. UpdateProcThreadAttribute.

Поддерживаемые атрибуты:

список_ручек

Последовательность хэндлов, которые будут наследоваться. close_fds должно быть true, если оно непустое.

Ручки должны быть временно сделаны наследуемыми os.set_handle_inheritable() при передаче конструктору Popen, иначе OSError будет выдана ошибка Windows ERROR_INVALID_PARAMETER (87).

Предупреждение

В многопоточном процессе соблюдайте осторожность, чтобы избежать утечки хэндлов, помеченных как наследуемые, при сочетании этой функции с одновременными вызовами других функций создания процесса, наследующих все хэндлы, таких как os.system(). Это также относится к стандартному перенаправлению хэндлов, которое временно создает наследуемые хэндлы.

Добавлено в версии 3.7.

Константы Windows

Модуль subprocess раскрывает следующие константы.

subprocess.STD_INPUT_HANDLE

Стандартное устройство ввода. Изначально это буфер ввода консоли, CONIN$.

subprocess.STD_OUTPUT_HANDLE

Стандартное устройство вывода. Изначально это активный буфер экрана консоли, CONOUT$.

subprocess.STD_ERROR_HANDLE

Устройство стандартных ошибок. Изначально это активный буфер экрана консоли, CONOUT$.

subprocess.SW_HIDE

Скрывает окно. Будет активировано другое окно.

subprocess.STARTF_USESTDHANDLES

Указывает, что атрибуты STARTUPINFO.hStdInput, STARTUPINFO.hStdOutput и STARTUPINFO.hStdError содержат дополнительную информацию.

subprocess.STARTF_USESHOWWINDOW

Указывает, что атрибут STARTUPINFO.wShowWindow содержит дополнительную информацию.

subprocess.CREATE_NEW_CONSOLE

Новый процесс имеет новую консоль, а не наследует консоль своего родителя (по умолчанию).

subprocess.CREATE_NEW_PROCESS_GROUP

Параметр Popen creationflags для указания того, что будет создана новая группа процессов. Этот флаг необходим для использования os.kill() на подпроцессе.

Этот флаг игнорируется, если указано CREATE_NEW_CONSOLE.

subprocess.ABOVE_NORMAL_PRIORITY_CLASS

Параметр Popen creationflags для указания того, что новый процесс будет иметь приоритет выше среднего.

Добавлено в версии 3.7.

subprocess.BELOW_NORMAL_PRIORITY_CLASS

Параметр Popen creationflags для указания того, что новый процесс будет иметь приоритет ниже среднего.

Добавлено в версии 3.7.

subprocess.HIGH_PRIORITY_CLASS

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

Добавлено в версии 3.7.

subprocess.IDLE_PRIORITY_CLASS

Параметр Popen creationflags для указания того, что новый процесс будет иметь холостой (самый низкий) приоритет.

Добавлено в версии 3.7.

subprocess.NORMAL_PRIORITY_CLASS

Параметр Popen creationflags для указания того, что новый процесс будет иметь нормальный приоритет. (по умолчанию)

Добавлено в версии 3.7.

subprocess.REALTIME_PRIORITY_CLASS

Параметр Popen creationflags для указания того, что новый процесс будет иметь приоритет реального времени. Практически никогда не следует использовать REALTIME_PRIORITY_CLASS, поскольку он прерывает системные потоки, управляющие вводом данных с мыши, клавиатуры и фоновой очисткой диска. Этот класс может быть уместен для приложений, которые «разговаривают» непосредственно с оборудованием или выполняют короткие задачи, которые должны иметь ограниченное количество прерываний.

Добавлено в версии 3.7.

subprocess.CREATE_NO_WINDOW

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

Добавлено в версии 3.7.

subprocess.DETACHED_PROCESS

Параметр Popen creationflags для указания того, что новый процесс не будет наследовать консоль своего родителя. Это значение нельзя использовать с CREATE_NEW_CONSOLE.

Добавлено в версии 3.7.

subprocess.CREATE_DEFAULT_ERROR_MODE

Параметр Popen creationflags для указания того, что новый процесс не наследует режим ошибок вызывающего процесса. Вместо этого новый процесс получает режим ошибок по умолчанию. Эта возможность особенно полезна для многопоточных приложений shell, которые работают с отключенными жесткими ошибками.

Добавлено в версии 3.7.

subprocess.CREATE_BREAKAWAY_FROM_JOB

Параметр Popen creationflags для указания того, что новый процесс не связан с заданием.

Добавлено в версии 3.7.

Старый высокоуровневый API

До Python 3.5 эти три функции составляли API высокого уровня для подпроцесса. Теперь вы можете использовать run() во многих случаях, но многие существующие программы вызывают эти функции.

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

Выполните команду, описанную args. Дождитесь завершения команды, затем верните атрибут returncode.

Код, которому нужно перехватить stdout или stderr, должен использовать run() вместо этого:

run(...).returncode

Чтобы подавить stdout или stderr, введите значение DEVNULL.

Приведенные выше аргументы являются лишь некоторыми общими. Полная сигнатура функции такая же, как у конструктора Popen - эта функция передает все переданные аргументы, кроме timeout, непосредственно в этот интерфейс.

Примечание

Не используйте stdout=PIPE или stderr=PIPE с этой функцией. Дочерний процесс будет блокироваться, если он генерирует достаточно вывода на трубу, чтобы заполнить буфер труб ОС, поскольку трубы не считываются.

Изменено в версии 3.3: Был добавлен таймаут.

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

Запустите команду с аргументами. Дождитесь завершения команды. Если код возврата был нулевым, то вернитесь, иначе поднимите CalledProcessError. Объект CalledProcessError будет иметь код возврата в атрибуте returncode. Если check_call() не смог запустить процесс, он распространит исключение, которое было поднято.

Код, которому нужно перехватить stdout или stderr, должен использовать run() вместо этого:

run(..., check=True)

Чтобы подавить stdout или stderr, введите значение DEVNULL.

Приведенные выше аргументы являются лишь некоторыми общими. Полная сигнатура функции такая же, как у конструктора Popen - эта функция передает все переданные аргументы, кроме timeout, непосредственно в этот интерфейс.

Примечание

Не используйте stdout=PIPE или stderr=PIPE с этой функцией. Дочерний процесс будет блокироваться, если он генерирует достаточно вывода на трубу, чтобы заполнить буфер труб ОС, поскольку трубы не считываются.

Изменено в версии 3.3: Был добавлен таймаут.

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None, **other_popen_kwargs)

Выполнить команду с аргументами и вернуть ее вывод.

Если код возврата был ненулевым, то возникает сообщение CalledProcessError. Объект CalledProcessError будет иметь код возврата в атрибуте returncode и любой вывод в атрибуте output.

Это эквивалентно:

run(..., check=True, stdout=PIPE).stdout

Приведенные выше аргументы являются лишь некоторыми общими. Полная сигнатура функции во многом совпадает с сигнатурой run() - большинство аргументов передается непосредственно через этот интерфейс. Существует одно отклонение API от поведения run(): при передаче input=None функция будет вести себя так же, как input=b'' (или input='', в зависимости от других аргументов), а не использовать стандартный входной файл родителя.

По умолчанию эта функция возвращает данные в виде закодированных байтов. Фактическая кодировка выходных данных может зависеть от вызываемой команды, поэтому декодирование в текст часто должно выполняться на уровне приложения.

Это поведение может быть отменено установкой text, encoding, errors или universal_newlines в True, как описано в Часто используемые аргументы и run().

Чтобы также зафиксировать стандартную ошибку в результате, используйте stderr=subprocess.STDOUT:

>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directory\n'

Добавлено в версии 3.1.

Изменено в версии 3.3: Был добавлен таймаут.

Изменено в версии 3.4: Добавлена поддержка аргумента ключевого слова input.

Изменено в версии 3.6: Были добавлены кодирование и ошибки. Подробности см. в run().

Добавлено в версии 3.7: text был добавлен как более читабельный псевдоним для universal_newlines.

Замена устаревших функций модулем subprocess

В этом разделе «a становится b» означает, что b может быть использовано в качестве замены a.

Примечание

Все функции «a» в этом разделе не работают (более или менее) молча, если выполняемая программа не может быть найдена; замены «b» вместо этого поднимают OSError.

Кроме того, замены, использующие check_output(), будут завершены с ошибкой CalledProcessError, если запрашиваемая операция выдает ненулевой код возврата. Вывод по-прежнему доступен как атрибут output поднятого исключения.

В следующих примерах мы предполагаем, что соответствующие функции уже импортированы из модуля subprocess.

Замена подстановки команд оболочки /bin/sh

output=$(mycmd myarg)

становится:

output = check_output(["mycmd", "myarg"])

Замена трубопровода оболочки

output=$(dmesg | grep hda)

становится:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

Вызов p1.stdout.close() после запуска p2 важен для того, чтобы p1 получил SIGPIPE, если p2 выйдет раньше p1.

В качестве альтернативы, для доверенного ввода, собственная поддержка конвейера оболочки может быть использована напрямую:

output=$(dmesg | grep hda)

становится:

output = check_output("dmesg | grep hda", shell=True)

Замена os.system()

sts = os.system("mycmd" + " myarg")
# becomes
retcode = call("mycmd" + " myarg", shell=True)

Примечания:

  • Вызов программы через shell обычно не требуется.

  • Возвращаемое значение call() кодируется иначе, чем os.system().

  • Функция os.system() игнорирует сигналы SIGINT и SIGQUIT во время выполнения команды, но вызывающая сторона должна делать это отдельно при использовании модуля subprocess.

Более реалистичный пример выглядит следующим образом:

try:
    retcode = call("mycmd" + " myarg", shell=True)
    if retcode < 0:
        print("Child was terminated by signal", -retcode, file=sys.stderr)
    else:
        print("Child returned", retcode, file=sys.stderr)
except OSError as e:
    print("Execution failed:", e, file=sys.stderr)

Замена семейства os.spawn

Пример P_NOWAIT:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

Пример P_WAIT:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

Пример вектора:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

Пример окружающей среды:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

Замена os.popen(), os.popen2(), os.popen3()

(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
(child_stdin,
 child_stdout,
 child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
 child_stdout,
 child_stderr) = (p.stdin, p.stdout, p.stderr)
(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

Обработка кода возврата происходит следующим образом:

pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
    print("There were some errors")
==>
process = Popen(cmd, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print("There were some errors")

Замена функций из модуля popen2

Примечание

Если аргумент cmd функции popen2 является строкой, команда выполняется через /bin/sh. Если это список, то команда выполняется напрямую.

(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

popen2.Popen3 и popen2.Popen4 в основном работают как subprocess.Popen, за исключением того, что:

  • Popen вызывает исключение при неудачном выполнении.

  • Аргумент capturestderr заменяется аргументом stderr.

  • stdin=PIPE и stdout=PIPE должны быть указаны.

  • popen2 закрывает все дескрипторы файлов по умолчанию, но вы должны указать close_fds=True с Popen, чтобы гарантировать такое поведение на всех платформах или прошлых версиях Python.

Функции вызова Legacy Shell

Этот модуль также предоставляет следующие унаследованные функции из модуля 2.x commands. Эти операции неявно вызывают системную оболочку, и ни одна из гарантий, описанных выше относительно безопасности и согласованности обработки исключений, не действует для этих функций.

subprocess.getstatusoutput(cmd)

Возврат (exitcode, output) от выполнения cmd в оболочке.

Выполните строку cmd в оболочке с помощью Popen.check_output() и верните кортеж (exitcode, output). Используется кодировка локали; подробнее см. примечания к Часто используемые аргументы.

Из вывода удаляется завершающая новая строка. Код выхода команды можно интерпретировать как код возврата подпроцесса. Пример:

>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> subprocess.getstatusoutput('cat /bin/junk')
(1, 'cat: /bin/junk: No such file or directory')
>>> subprocess.getstatusoutput('/bin/junk')
(127, 'sh: /bin/junk: not found')
>>> subprocess.getstatusoutput('/bin/kill $$')
(-15, '')

Availability: POSIX & Windows.

Изменено в версии 3.3.4: Была добавлена поддержка Windows.

Теперь функция возвращает (exitcode, output), а не (status, output), как это было в Python 3.3.3 и более ранних версиях. exitcode имеет то же значение, что и returncode.

subprocess.getoutput(cmd)

Возвращает вывод (stdout и stderr) о выполнении cmd в оболочке.

Подобно getstatusoutput(), за исключением того, что код выхода игнорируется, а возвращаемым значением является строка, содержащая вывод команды. Пример:

>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'

Availability: POSIX & Windows.

Изменено в версии 3.3.4: Добавлена поддержка Windows

Примечания

Преобразование последовательности аргументов в строку в Windows

В Windows последовательность args преобразуется в строку, которая может быть разобрана с помощью следующих правил (которые соответствуют правилам, используемым средой выполнения MS C):

  1. Аргументы разделены пробелом, который является либо пробелом, либо символом табуляции.

  2. Строка, окруженная двойными кавычками, интерпретируется как один аргумент, независимо от наличия пробелов. Строка в кавычках может быть встроена в аргумент.

  3. Двойная кавычка, которой предшествует обратная косая черта, интерпретируется как буквальная двойная кавычка.

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

  5. Если обратные косые черты непосредственно предшествуют двойной кавычке, каждая пара обратных косых черт интерпретируется как буквальная обратная косая черта. Если количество обратных косых черт нечетное, то последняя обратная косая черта экранирует следующую двойную кавычку, как описано в правиле 3.

См.также

shlex

Модуль, предоставляющий функцию для разбора и вывода командных строк.

Вернуться на верх