Перейти к содержимому

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

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


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

python
os.system
os.spawn*

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

Смотрите также

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

Доступность: не Android, не iOS, не WASI

Этот модуль не поддерживается на мобильных платформах или платформах WebAssembly.

Использование модуля 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 и stderr, установленными в PIPE. Аргументы stdout и stderr не могут быть указаны одновременно с capture_output. Если нужно захватить и объединить оба потока в один, установите stdout в PIPE, а stderr в STDOUT, вместо использования capture_output.

timeout может быть задан в секундах; он внутренне передаётся в Popen.communicate(). Если тайм-аут истекает, дочерний процесс завершается и ожидается. Исключение TimeoutExpired возбуждается повторно после завершения дочернего процесса. Само начальное создание процесса не может быть прервано на многих платформенных API, поэтому нет гарантии получить исключение тайм-аута до тех пор, пока не пройдёт хотя бы время, необходимое для создания процесса.

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

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

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

Если env не равно None, это должно быть отображение (mapping), определяющее переменные окружения для нового процесса; они используются вместо стандартного поведения наследования окружения текущего процесса. Оно передаётся непосредственно в Popen. Это отображение может быть типа «str → str» на любой платформе или «bytes → bytes» на платформах POSIX, подобно os.environ или os.environb.

Примеры:

python
>>> subprocess.run(["ls", "-l"])  # не захватывает вывод
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.

Изменено в версии 3.12: Изменён порядок поиска оболочки Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате помещение вредоносной программы с именем cmd.exe в текущий каталог больше не работает.

class subprocess.CompletedProcess

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

args

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

returncode

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

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

stdout

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

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

stderr

Захваченный stderr дочернего процесса. Последовательность байтов или строка, если run() был вызван с указанием encoding, errors или 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 и указывает, что должен быть открыт канал (pipe) к стандартному потоку. Наиболее полезно с Popen.communicate().

subprocess.STDOUT

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

exception subprocess.SubprocessError

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

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

exception subprocess.TimeoutExpired

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

cmd

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

timeout

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

output

Вывод дочернего процесса, если он был захвачен с помощью run() или check_output(). В противном случае – None. Это всегда bytes, когда какой-либо вывод был захвачен независимо от настройки text=True. Он может остаться None вместо b'', если вывод не наблюдался.

stdout

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

stderr

Вывод stderr дочернего процесса, если он был захвачен с помощью run(). В противном случае – None. Это всегда bytes, когда вывод stderr был захвачен независимо от настройки text=True. Он может остаться None вместо b'', если вывод stderr не наблюдался.

Добавлено в версии 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

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

stderr

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

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

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

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

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

stdin, stdout и stderr задают файловые дескрипторы стандартного ввода, стандартного вывода и стандартного вывода ошибок выполняемой программы соответственно. Допустимыми значениями являются None, PIPE, DEVNULL, существующий файловый дескриптор (положительное целое число) и существующий объект файла с корректным файловым дескриптором. При настройках по умолчанию None перенаправление не происходит. PIPE указывает, что должен быть создан новый канал для дочернего процесса. DEVNULL указывает, что будет использоваться специальный файл os.devnull. Кроме того, 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 в первую очередь из-за улучшенного управления потоком выполнения, которое он предлагает по сравнению с большинством системных оболочек, и при этом хотите удобного доступа к другим возможностям оболочки, таким как конвейеры, подстановка имен файлов по шаблону, подстановка переменных окружения и замена ~ на домашний каталог пользователя. Однако обратите внимание, что сам Python предоставляет реализации многих подобных оболочечных возможностей (в частности, glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser() и shutil).

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

Примечание

Перед использованием shell=True прочтите раздел Соображения безопасности.

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

Popen ConstructorКонструктор Popen

Создание и управление процессами на низком уровне в этом модуле осуществляется классом 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, process_group=None)

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

args должен быть последовательностью аргументов программы или одной строкой, либо path-like объектом. По умолчанию выполняемой программой является первый элемент в 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. Использование полного пути устраняет все эти вариации.

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

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

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

Примечание

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

python
>>> 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) # Успех!

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

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

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

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

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

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

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

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

Примечание

Перед использованием shell=True прочтите раздел Соображения безопасности.

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

  • 0 означает отсутствие буферизации (чтение и запись – один системный вызов, может вернуть меньше данных).

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

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

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

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

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

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

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

Изменено в версии 3.12: Изменен порядок поиска оболочки Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате помещение вредоносной программы с именем cmd.exe в текущий каталог больше не работает.

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

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

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

Параметр preexec_fn НЕБЕЗОПАСНО использовать при наличии потоков в вашем приложении. Дочерний процесс может заблокироваться (deadlock) до вызова exec.

Примечание

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

Изменено в версии 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 может быть строкой, байтами или путеподобным объектом. В POSIX функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу является относительным.

Изменено в версии 3.6: Параметр cwd принимает путеподобный объект в POSIX.

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

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

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

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

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

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

Если process_group является неотрицательным целым числом, системный вызов setpgid(0, value) будет выполнен в дочернем процессе перед запуском подпроцесса.

Изменено в версии 3.11: Добавлен process_group.

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

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

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

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

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

Примечание

Указание user не приведёт к сбросу существующих дополнительных членств в группах! Вызывающий также должен передать extra_groups=(), чтобы уменьшить членство в группах дочернего процесса в целях безопасности.

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

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

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

Если env не является None, он должен быть отображением, определяющим переменные окружения для нового процесса; они используются вместо поведения по умолчанию, заключающегося в наследовании окружения текущего процесса. Это отображение может быть str → str на любой платформе или bytes → bytes на POSIX-платформах, во многом как os.environ или os.environb.

Примечание

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

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

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

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

Если задан, startupinfo будет объектом STARTUPINFO, который передаётся базовой функции CreateProcess.

Если задан, creationflags может быть одним или несколькими из следующих флагов:

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

Изменено в версии 3.10: Добавлен параметр pipesize.

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

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

Popen и другие функции в этом модуле, которые его используют, вызывают событие аудита subprocess.Popen с аргументами executable, args, cwd и env. Значение для args может быть одной строкой или списком строк в зависимости от платформы.

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

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

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

ExceptionsИсключения

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

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

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

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

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

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

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

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

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

В Windows пакетные файлы (*.bat или *.cmd) могут быть запущены операционной системой в системной оболочке независимо от аргументов, переданных этой библиотеке. Это может привести к тому, что аргументы будут обрабатываться по правилам оболочки, но без какого-либо экранирования со стороны Python. Если вы намеренно запускаете пакетный файл с аргументами из ненадёжных источников, рассмотрите возможность передачи shell=True, чтобы позволить Python экранировать специальные символы. См. gh-114539 для дополнительного обсуждения.

Popen ObjectsОбъекты Popen

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

Popen.poll()

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

Popen.wait(timeout=None)

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

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

Примечание

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

Примечание

Когда timeout не является None и платформа это поддерживает, используется эффективный событийно-ориентированный механизм для ожидания завершения процесса:

  • Linux >= 5.3 использует os.pidfd_open() + select.poll()

  • macOS и другие варианты BSD используют select.kqueue() + KQ_FILTER_PROC + KQ_NOTE_EXIT

  • Windows использует WaitForSingleObject

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

Примечание

Используйте модуль asyncio для асинхронного ожидания: см. asyncio.create_subprocess_exec.

Изменено в версии 3.3: добавлен timeout.

Изменено в версии 3.15: если timeout не равен None, используется эффективная событийно-ориентированная реализация на Linux >= 5.3 и macOS / BSD.

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. Перехват этого исключения и повторный вызов communication не приведет к потере выходных данных. Передача input в последующий после тайм-аута вызов communicate() является неопределенным поведением и может стать ошибкой в будущем.

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

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

После того, как вызов communicate() вызывает TimeoutExpired, не вызывайте wait(). Используйте дополнительный вызов communicate(), чтобы завершить обработку каналов и заполнить атрибут returncode.

Примечание

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

Изменено в версии 3.3: добавлен timeout.

Popen.send_signal(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, или аргумент text или universal_newlines был True, поток является текстовым, в противном случае – байтовым. Если аргумент stdin не был PIPE, этот атрибут равен None.

Popen.stdout

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

Popen.stderr

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

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

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

Popen.pid

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

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

Popen.returncode

Код возврата дочернего процесса. Изначально равен None, returncode устанавливается вызовом методов poll(), wait() или communicate(), если они обнаруживают, что процесс завершился.

Значение None указывает, что процесс ещё не завершился на момент последнего вызова метода.

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

Когда shell=True, код возврата отражает статус выхода самой оболочки (например, /bin/sh), которая может отображать сигналы в коды, такие как 128+N. За подробностями обращайтесь к документации оболочки (например, раздел Exit Status руководства Bash).

Windows Popen HelpersВспомогательные классы Popen для Windows

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

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

Частичная поддержка структуры Windows STARTUPINFO используется для создания Popen. Следующие атрибуты могут быть заданы передачей их в качестве аргументов только по ключу.

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

dwFlags

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

python
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.

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

handle_list

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

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

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

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

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

Windows ConstantsКонстанты 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.STARTF_FORCEONFEEDBACK

Параметр STARTUPINFO.dwFlags, указывающий, что курсор мыши Работа в фоновом режиме будет отображаться во время запуска процесса. Это поведение по умолчанию для процессов с графическим интерфейсом.

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

subprocess.STARTF_FORCEOFFFEEDBACK

Параметр STARTUPINFO.dwFlags, указывающий, что курсор мыши не будет изменяться при запуске процесса.

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

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, указывающий, что новый процесс не наследует режим ошибок вызывающего процесса. Вместо этого новый процесс получает режим ошибок по умолчанию. Эта функция особенно полезна для многопоточных приложений оболочки, которые работают с отключенными аппаратными ошибками.

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

subprocess.CREATE_BREAKAWAY_FROM_JOB

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

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

Older high-level APIБолее старый высокоуровневый 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() вместо этого:

python
run(...).returncode

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

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

Примечание

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

Изменено в версии 3.3: добавлен timeout.

Изменено в версии 3.12: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате помещение вредоносной программы с именем cmd.exe в текущий каталог больше не работает.

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() вместо этого:

python
run(..., check=True)

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

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

Примечание

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

Изменено в версии 3.3: добавлен timeout.

Изменено в версии 3.12: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате помещение вредоносной программы с именем cmd.exe в текущий каталог больше не работает.

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.

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

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

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

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

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

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

python
>>> 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: timeout был добавлен.

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

Изменено в версии 3.6: encoding и errors были добавлены. Подробнее см. run().

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

Изменено в версии 3.12: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменяются на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате подбрасывание вредоносной программы с именем cmd.exe в текущий каталог больше не работает.

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

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

Примечание

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

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

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

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

bash
output=$(mycmd myarg)

становится:

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

Replacing shell pipelineЗамена конвейера оболочки

bash
output=$(dmesg | grep hda)

становится:

python
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Разрешить p1 получать SIGPIPE, если p2 завершится.
output = p2.communicate()[0]

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

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

bash
output=$(dmesg | grep hda)

становится:

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

Замена os.system()

python
sts = os.system("mycmd" + " myarg")
# становится
retcode = call("mycmd" + " myarg", shell=True)

Примечания:

  • Обычно не требуется вызывать программу через оболочку.

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

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

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

python
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:

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

Пример P_WAIT:

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

Пример Vector:

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

Пример окружения:

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

Замена os.popen()

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

python
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")

Legacy Shell Invocation FunctionsУстаревшие функции вызова оболочки

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

subprocess.getstatusoutput(cmd, *, encoding=None, errors=None)

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

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

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

python
>>> 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, '')

Доступность: Unix, Windows.

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

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

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

subprocess.getoutput(cmd, *, encoding=None, errors=None)

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

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

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

Доступность: Unix, Windows.

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

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

NotesПримечания

Timeout BehaviorПоведение при тайм-ауте

При использовании параметра timeout в таких функциях, как run(), Popen.wait() или Popen.communicate(), следует учитывать следующее поведение:

  1. Задержка создания процесса: Само начальное создание процесса нельзя прервать во многих платформенных API. Это означает, что даже при указании тайм-аута нет гарантии, что исключение тайм-аута возникнет раньше, чем завершится создание процесса.

  2. Очень малые значения тайм-аута: Установка очень малых значений тайм-аута (например, несколько миллисекунд) может привести к почти немедленным исключениям TimeoutExpired, поскольку создание процесса и планирование системой по своей природе требуют времени.

Converting an argument sequence to a string on WindowsПреобразование последовательности аргументов в строку в Windows

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

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

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

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

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

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

Смотрите также

shlex

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

Отключить использование posix_spawn()

В Linux subprocess по умолчанию использует системный вызов vfork() внутри, когда это безопасно, вместо fork(). Это значительно повышает производительность.

python
subprocess._USE_POSIX_SPAWN = False  # См. CPython issue gh-NNNNNN.

Устанавливать значение false можно без риска в любой версии Python. На старых или новых версиях, где это не поддерживается, оно не будет иметь эффекта. Не следует полагать, что атрибут доступен для чтения. Несмотря на название, значение true не означает, что соответствующая функция будет использована – только что она может быть.

Сообщайте об ошибках каждый раз, когда вам приходится использовать эти частные «ручки» (private knobs), вместе со способом воспроизведения обнаруженной проблемы. Указывайте ссылку на этот отчёт об ошибке в комментарии к вашему коду.

Добавлено в версии 3.8: _USE_POSIX_SPAWN