subprocess — Управление дочерними процессами
Исходный код: Lib/subprocess.py
Модуль subprocess позволяет запускать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать их коды возврата. Этот модуль призван заменить несколько более старых модулей и функций:
os.system os.spawn*
Информация о том, как модуль subprocess может быть использован для замены этих модулей и функций, приведена в следующих разделах.
См. также
PEP 324 — PEP, предлагающий модуль subprocess
1. Использование модуля subprocess
Рекомендуемый подход к вызову дочерних процессов — использование функции run() для всех случаев, которые она может обработать. Для более сложных случаев можно напрямую использовать интерфейс Popen.
Функция run() была добавлена в Python 3.5; если вам нужно сохранить совместимость со старыми версиями, см. раздел Старый высокоуровневый API.
-
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False) -
Запустить команду, описанную в args. Дождаться завершения команды, затем вернуть экземпляр
CompletedProcess.Приведенные выше аргументы — это лишь наиболее распространённые, описанные ниже в Часто используемые аргументы (отсюда использование ключевых аргументов в сокращённой сигнатуре). Полная сигнатура функции в основном такая же, как у конструктора
Popen— за исключением timeout, input и check, все аргументы этой функции передаются в этот интерфейс.По умолчанию это не捕获stdout или stderr. Для этого передайте
PIPEдля аргументов stdout и/или stderr.Аргумент timeout передаётся в
Popen.communicate(). Если таймаут истечёт, дочерний процесс будет убит и дождаться его завершения. ИсключениеTimeoutExpiredбудет повторно возбуждено после завершения дочернего процесса.Аргумент input передаётся в
Popen.communicate()и, таким образом, в стандартный ввод дочернего процесса. Если он используется, он должен быть последовательностью байтов или строкой, еслиuniversal_newlines=True. При использовании внутренний объектstdin=PIPEавтоматически создаётся сstdin=PIPE, и аргумент stdin также не может быть использован.Если check имеет значение true, и процесс завершается с ненулевым кодом возврата, будет возбуждено исключение
CalledProcessError. Атрибуты этого исключения содержат аргументы, код возврата и stdout и stderr, если они были захвачены.Примеры:
>>> 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"], stdout=subprocess.PIPE) 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')Введено в версии 3.5.
-
class subprocess.CompletedProcess -
Значение, возвращаемое из
run(), представляющее процесс, который завершился.-
args -
Аргументы, используемые для запуска процесса. Это может быть список или строка.
-
returncode -
Код завершения дочернего процесса. Обычно код завершения 0 означает, что он завершился успешно.
Отрицательное значение
-Nуказывает, что дочерний процесс был завершен сигналомN(только POSIX).
-
stdout -
Захваченный stdout дочернего процесса. Последовательность байтов или строка, если
run()был вызван сuniversal_newlines=True.Noneесли stdout не был захвачен.Если вы запустили процесс с
stderr=subprocess.STDOUT, stdout и stderr будут объединены в этом атрибуте, иstderrбудетNone.
-
stderr -
Захваченный stderr дочернего процесса. Последовательность байтов или строка, если
run()был вызван сuniversal_newlines=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 -
Псевдоним для output, для симметрии с
stderr.
-
stderr -
Вывод stderr дочернего процесса, если он был захвачен
run(). В противном случае,None.
Введено в версии 3.3.
Изменено в версии 3.5: Добавлены атрибуты stdout и stderr
-
-
exception subprocess.CalledProcessError -
Подкласс
SubprocessError, генерируется, когда процесс, запущенный с помощьюcheck_call()илиcheck_output(), возвращает код завершения, отличный от нуля.-
returncode -
Код завершения дочернего процесса. Если процесс завершился из-за сигнала, это будет отрицательное число сигнала.
-
cmd -
Команда, используемая для запуска дочернего процесса.
-
output -
Вывод дочернего процесса, если он был перехвачен
run()илиcheck_output(). В противном случае,None.
-
stdout -
Псевдоним для output, для симметрии с
stderr.
-
stderr -
Вывод stderr дочернего процесса, если он был перехвачен
run(). В противном случае,None.
Изменено в версии 3.5: Добавлены атрибуты stdout и stderr
-
1.1. Часто используемые аргументы
Для поддержки широкого спектра случаев использования конструктор Popen (и удобные функции) принимают большое количество необязательных аргументов. Для большинства типичных случаев использования многие из этих аргументов можно без опасений оставить со значениями по умолчанию. Аргументы, которые чаще всего требуются, это:
args требуется для всех вызовов и должен быть строкой или последовательностью аргументов программы. Использование последовательности аргументов обычно предпочтительнее, так как это позволяет модулю позаботиться об обработке необходимых экранирований и цитирования аргументов (например, для разрешения пробелов в именах файлов). Если передаётся строка, то shell должен быть True (см. ниже), или же строка должна просто указывать имя выполняемой программы без указания аргументов.
stdin, stdout и stderr задают стандартные входные, выходные и выходные потоки выполняемой программы соответственно. Допустимые значения — PIPE, DEVNULL, существующий дескриптор файла (положительное целое число), существующий объект файла и None. PIPE указывает, что должен быть создан новый канал для дочернего процесса. DEVNULL указывает, что будет использован специальный файл os.devnull. При значениях по умолчанию None, перенаправления не происходит; дескрипторы файлов дочернего процесса наследуются от родительского процесса. Кроме того, stderr может быть STDOUT, что указывает, что данные stderr дочернего процесса должны быть перехвачены в тот же дескриптор файла, что и stdout.
Если universal_newlines равно False, объекты файлов stdin, stdout и stderr будут открыты как бинарные потоки, и преобразование символов конца строки не выполняется.
Если universal_newlines равно True, эти объекты файлов будут открыты как текстовые потоки в режиме универсальных символов конца строки с использованием кодировки, возвращаемой функцией locale.getpreferredencoding(False). Для stdin символы конца строки '\n' на входе будут преобразованы в разделитель строк по умолчанию os.linesep. Для stdout и stderr все символы конца строки в выводе будут преобразованы в '\n'. Для получения дополнительной информации обратитесь к документации класса io.TextIOWrapper, когда аргумент newline конструктору этого класса имеет значение None.
Примечание
Атрибут 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.
1.2. Конструктор 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=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=()) -
Выполнение дочерней программы в новом процессе. В POSIX, класс использует поведение, подобное
os.execvp(), для выполнения дочерней программы. В Windows, класс использует функцию WindowsCreateProcess(). Аргументы дляPopenследующие.args должен быть последовательностью аргументов программы или одной строкой. По умолчанию, программа для выполнения — это первый элемент в args, если args является последовательностью. Если args является строкой, интерпретация зависит от платформы и описана ниже. Обратитесь к аргументам shell и executable для дополнительных различий от стандартного поведения. Если не указано иное, рекомендуется передавать args как последовательность.
В 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()работает со строками.Аргумент 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для запуска пакетного файла или консольной исполняемой программы.Примечание
Перед использованием
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, как ожидало большинство кодов.Аргумент executable указывает заменяющую программу для выполнения. Он редко используется. Когда
shell=False, executable заменяет программу для выполнения, указанную в args. Однако, исходные args всё ещё передаются программе. Большинство программ обрабатывают программу, указанную в args, как имя команды, которая может отличаться от фактически выполняемой программы. В POSIX, имя args становится отображаемым именем исполняемого файла в утилитах, таких как ps. Еслиshell=True, в POSIX аргумент executable указывает заменяющую оболочку для стандартной/bin/sh.stdin, stdout и stderr задают стандартный ввод, стандартный вывод и стандартную ошибку выполняемой программы соответственно. Допустимые значения —
PIPE,DEVNULL, существующий дескриптор файла (положительное целое число), существующий объект файла иNone.PIPEуказывает, что должен быть создан новый канал для дочернего процесса.DEVNULLуказывает, что будет использован специальный файлos.devnull. При стандартных настройкахNone, перенаправление не произойдёт; дескрипторы файлов дочернего процесса будут унаследованы от родительского процесса. Кроме того, stderr может бытьSTDOUT, что указывает, что данные об ошибках приложения должны быть захвачены в тот же дескриптор файла, что и вывод.Если preexec_fn задан как вызываемый объект, этот объект будет вызван в дочернем процессе непосредственно перед выполнением дочернего процесса. (Только POSIX)
Предупреждение
Параметр preexec_fn небезопасен для использования в многопоточных приложениях. Дочерний процесс может заблокироваться перед вызовом exec. Если вам необходимо его использовать, сделайте его простым! Минимизируйте количество вызовов библиотек.
Примечание
Если вам нужно изменить среду для дочернего процесса, используйте параметр env вместо этого в preexec_fn. Параметр start_new_session может заменить ранее распространённое использование preexec_fn для вызова os.setsid() в дочернем процессе.
Если close_fds имеет значение true, все дескрипторы файлов, кроме
0,1и2, будут закрыты перед выполнением дочернего процесса. (Только POSIX). Значение по умолчанию зависит от платформы: всегда true в POSIX. В Windows оно равно true, когда stdin/stdout/stderr равныNone, в противном случае — false. В Windows, если close_fds имеет значение true, то дочерний процесс не унаследует дескрипторы. Обратите внимание, что в Windows нельзя установить close_fds в true и одновременно перенаправлять стандартные дескрипторы, задавая stdin, stdout или stderr.Изменено в версии 3.2: Значение по умолчанию для close_fds было изменено с
Falseна описанное выше.pass_fds — это необязательная последовательность дескрипторов файлов, которые необходимо оставить открытыми между родительским и дочерним процессами. Передача pass_fds принудительно устанавливает close_fds в
True. (Только POSIX)Добавлен в версии 3.2: Параметр pass_fds был добавлен.
Если cwd не
None, функция изменяет рабочую директорию на cwd перед выполнением дочернего процесса. В частности, функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу является относительным.Если restore_signals имеет значение true (по умолчанию), все сигналы, которые Python установил в SIG_IGN, восстанавливаются до SIG_DFL в дочернем процессе перед выполнением exec. В настоящее время это включает сигналы SIGPIPE, SIGXFZ и SIGXFSZ. (Только POSIX)
Изменено в версии 3.2: restore_signals был добавлен.
Если start_new_session имеет значение true, вызов системы setsid() будет выполнен в дочернем процессе перед выполнением дочернего процесса. (Только POSIX)
Изменено в версии 3.2: start_new_session был добавлен.
Если env не
None, он должен быть отображением, определяющим переменные среды для нового процесса; они используются вместо стандартного поведения наследования среды текущего процесса.Примечание
Если указан, env должен содержать все переменные, необходимые для выполнения программы. В Windows, для запуска side-by-side assembly указанное env должно содержать корректную
SystemRoot.Если universal_newlines равно
True, объекты файлов stdin, stdout и stderr открываются как текстовые потоки в режиме универсальных новых строк, как описано выше в Часто используемые аргументы, в противном случае они открываются как двоичные потоки. -
Если задано, startupinfo будет объектом
STARTUPINFO, который передаётся подлежащейCreateProcessфункции. creationflags, если задано, может бытьCREATE_NEW_CONSOLEилиCREATE_NEW_PROCESS_GROUP. (Только Windows)Объекты Popen поддерживаются как менеджеры контекста через оператор
with: при выходе стандартные дескрипторы файлов закрываются, и процесс ожидает завершения.with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read())Изменено в версии 3.2: Добавлена поддержка менеджера контекста.
1.3. Исключения
Исключения, поднятые в дочернем процессе до того, как новая программа начнёт выполняться, будут повторно подняты в родительском процессе. Кроме того, у объекта исключения будет один дополнительный атрибут, называемый child_traceback, который представляет собой строку, содержащую информацию об отслеживании стека с точки зрения дочернего процесса.
Наиболее распространённое исключение — OSError. Оно возникает, например, при попытке выполнить несуществующий файл. Приложения должны быть готовы к исключениям OSError.
Исключение ValueError будет поднято, если Popen вызывается с неверными аргументами.
check_call() и check_output() поднимут исключение CalledProcessError, если вызванный процесс вернёт код возврата, отличный от нуля.
Все функции и методы, принимающие параметр timeout, такие как call() и Popen.communicate(), поднимут исключение TimeoutExpired, если таймаут истечёт до завершения процесса.
Все исключения, определённые в данном модуле, наследуются от SubprocessError.
Новое в версии 3.3: Базовый класс SubprocessError был добавлен.
2. Учёт мер безопасности
В отличие от некоторых других функций popen, эта реализация никогда не будет неявно вызывать системную оболочку. Это означает, что все символы, включая метасимволы оболочки, могут безопасно передаваться дочерним процессам. Если оболочка вызывается явно, посредством shell=True, приложение несёт ответственность за обеспечение того, чтобы все пробелы и метасимволы были должным образом приведены в соответствие, чтобы избежать уязвимостей внедрения оболочки.
При использовании shell=True, функция shlex.quote() может использоваться для правильного экранирования пробелов и метасимволов оболочки в строках, которые будут использоваться для построения команд оболочки.
3. Объекты Popen
Объекты класса Popen имеют следующие методы:
-
Popen.poll() -
Проверка завершения дочернего процесса. Устанавливает и возвращает атрибут
returncode.
-
Popen.wait(timeout=None) -
Ожидание завершения дочернего процесса. Устанавливает и возвращает атрибут
returncode.Если процесс не завершается через timeout секунд, возникает исключение
TimeoutExpired. Безопасно перехватывать это исключение и повторно пытаться ожидать завершения.Примечание
Это приведёт к блокировке при использовании
stdout=PIPEилиstderr=PIPE, если дочерний процесс генерирует достаточно вывода в канал, чтобы заблокировать ожидание, пока буфер канала ОС не примет больше данных. ИспользуйтеPopen.communicate()при использовании каналов, чтобы избежать этого.Примечание
Функция реализована с использованием цикла busy (неблокирующий вызов и короткие задержки). Используйте модуль
asyncioдля асинхронного ожидания: см.asyncio.create_subprocess_exec.Изменено в версии 3.3: Добавлен параметр timeout.
Устарело начиная с версии 3.4: Не используйте параметр endtime. Он был непреднамеренно доступен в 3.3, но не документирован, так как он предназначался для использования внутри модуля. Используйте timeout вместо этого.
-
Popen.communicate(input=None, timeout=None) -
Взаимодействие с процессом: отправка данных в стандартный ввод. Чтение данных из стандартного вывода и стандартной ошибки до достижения конца файла. Ожидание завершения процесса. Необязательный аргумент input должен содержать данные, которые будут отправлены дочернему процессу, или
None, если данные отправлять не нужно. Тип input должен быть байтовым или, если universal_newlines былоTrue, строковым.communicate()возвращает кортеж(stdout_data, stderr_data). Данные будут байтовыми или, если universal_newlines былоTrue, строковыми.Обратите внимание, что если вы хотите отправить данные в стандартный ввод процесса, вам нужно создать объект 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: Добавлен параметр 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(). Если аргумент universal_newlines былTrue, поток — текстовый, в противном случае — байтовый. Если аргумент stdin не былPIPE, этот атрибут —None.
-
Popen.stdout -
Если аргумент stdout был
PIPE, это атрибут — это объект потока для чтения, возвращаемый функциейopen(). Чтение из потока предоставляет вывод дочернего процесса. Если аргумент universal_newlines былTrue, поток является текстовым, в противном случае — байтовым потоком. Если аргумент stdout не былPIPE, этот атрибут —None.
-
Popen.stderr -
Если аргумент stderr был
PIPE, этот атрибут — это объект потока для чтения, возвращаемый функциейopen(). Чтение из потока предоставляет вывод об ошибках дочернего процесса. Если аргумент universal_newlines былTrue, поток является текстовым, в противном случае — байтовым потоком. Если аргумент stderr не былPIPE, этот атрибут —None.
Предупреждение
Используйте communicate() вместо .stdin.write, .stdout.read или .stderr.read, чтобы избежать тупиковых ситуаций из-за заполнения буферов каналов ОС и блокирования дочернего процесса.
-
Popen.pid -
Идентификатор процесса (PID) дочернего процесса.
Обратите внимание, что если вы установили аргумент shell в
True, это PID запущенной оболочки.
-
Popen.returncode -
Код возврата дочернего процесса, устанавливаемый функциями
poll()иwait()(и косвенноcommunicate()). ЗначениеNoneуказывает, что процесс ещё не завершился.Отрицательное значение
-Nуказывает, что дочерний процесс был завершен сигналомN(только POSIX).
4. Windows Popen Helpers
Класс STARTUPINFO и следующие константы доступны только на Windows.
-
class subprocess.STARTUPINFO -
Частичная поддержка структуры Windows STARTUPINFO используется для создания
Popen.-
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.
-
4.1. Константы
Модуль 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для указания создания новой группы процессов. Этот флаг необходим для использованияos.kill()на дочернем процессе.Этот флаг игнорируется, если задан
CREATE_NEW_CONSOLE.
5. Старые высокоуровневые API
До Python 3.5 эти три функции составляли высокоуровневый API для subprocess. Теперь вы можете использовать run() во многих случаях, но много существующего кода использует эти функции.
-
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None) -
Выполняет команду, описанную в args. Ожидает завершения команды, затем возвращает атрибут
returncode.Это эквивалентно:
run(...).returncode
(кроме того, что параметры input и check не поддерживаются)
Приведенные выше аргументы — это лишь наиболее распространённые. Полная сигнатура функции в значительной степени такая же, как у конструктора
Popen— эта функция передаёт все предоставленные аргументы, кроме timeout, непосредственно этому интерфейсу.Примечание
Не используйте
stdout=PIPEилиstderr=PIPEс этой функцией. Дочерний процесс заблокируется, если он сгенерирует достаточно вывода в канал, чтобы заполнить буфер канала ОС, так как каналы не читаются.Изменено в версии 3.3: Добавлен параметр timeout.
-
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None) -
Выполнить команду с аргументами. Дождаться завершения команды. Если код возврата был равен нулю, то вернуть значение, иначе выбросить исключение
CalledProcessError. ОбъектCalledProcessErrorбудет содержать код возврата в атрибутеreturncode.Это эквивалентно:
run(..., check=True)
(за исключением того, что параметр input не поддерживается)
Приведенные выше аргументы — это лишь наиболее распространённые. Полная сигнатура функции в значительной степени аналогична сигнатуре конструктора
Popen— эта функция передает все предоставленные аргументы, кроме timeout, непосредственно в этот интерфейс.Примечание
Не используйте
stdout=PIPEилиstderr=PIPEс этой функцией. Дочерний процесс будет блокироваться, если он сгенерирует достаточно вывода в канал, чтобы заполнить буфер канала ОС, так как каналы не читаются.Изменено в версии 3.3: Добавлен параметр timeout.
-
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None) -
Выполнить команду с аргументами и вернуть её вывод.
Если код возврата был отличным от нуля, то генерируется исключение
CalledProcessError. ОбъектCalledProcessErrorбудет содержать код возврата в атрибутеreturncodeи любой вывод в атрибутеoutput.Это эквивалентно:
run(..., check=True, stdout=PIPE).stdout
Приведённые выше аргументы — это лишь наиболее распространённые. Полная сигнатура функции в значительной степени аналогична сигнатуре
run()— большинство аргументов передаются непосредственно в этот интерфейс. Однако явное указаниеinput=Noneдля наследования входного файла стандартного потока родителя не поддерживается.По умолчанию эта функция будет возвращать данные в виде закодированных байтов. Фактическая кодировка выходных данных может зависеть от вызываемой команды, поэтому декодирование в текст часто требует обработки на уровне приложения.
Это поведение может быть переопределено установкой universal_newlines в
Trueкак описано выше в Часто используемые аргументы.Чтобы также получить стандартную ошибку в результате, используйте
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: Добавлен параметр timeout.
Изменено в версии 3.4: Добавлена поддержка параметра input.
6. Замена устаревших функций модулем subprocess
В этом разделе «a заменяется на b» означает, что b может использоваться вместо a.
Примечание
Все функции «a» в этом разделе молчаливо терпят неудачу (в большей или меньшей степени), если исполняемую программу не удаётся найти; замены «b» вместо этого генерируют исключение OSError.
Кроме того, замены с использованием check_output() завершатся ошибкой с CalledProcessError, если запрошенная операция возвращает код ошибки, отличный от нуля. Вывод по-прежнему доступен как атрибут output сгенерированного исключения.
В следующих примерах предполагается, что соответствующие функции уже импортированы из модуля subprocess.
6.1. Замена оболочки /bin/sh в обратных кавычках
output=`mycmd myarg`
заменяется на:
output = check_output(["mycmd", "myarg"])
6.2. Замена конвейера оболочки
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)
6.3. Замена os.system()
sts = os.system("mycmd" + " myarg")
# becomes
sts = call("mycmd" + " myarg", shell=True)
Примечания:
- Вызов программы через оболочку обычно не требуется.
Более реалистичный пример выглядит так:
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)
6.4. Замена семейства 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"})
6.5. Замена 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")
6.6. Замена функций из модуля 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.
7. Функции устаревшего вызова оболочки
Этот модуль также предоставляет следующие устаревшие функции из модуля 2.x commands. Эти операции неявно вызывают оболочку системы, и ни одно из описанных выше гарантий безопасности и согласованности обработки исключений не распространяется на эти функции.
-
subprocess.getstatusoutput(cmd) -
Возвращает
(status, output)выполнения cmd в оболочке.Выполняет строку cmd в оболочке с
Popen.check_output()и возвращает кортеж 2-х элементов(status, output). Используется режим универсальных новых строк; см. примечания к Часто используемые аргументы для получения более подробной информации.Конец строки удаляется из вывода. Код выхода команды можно интерпретировать по правилам для функции C
wait(). Пример:>>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') (256, 'cat: /bin/junk: No such file or directory') >>> subprocess.getstatusoutput('/bin/junk') (256, 'sh: /bin/junk: not found')Доступность: POSIX & Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows
-
subprocess.getoutput(cmd) -
Возвращает вывод (stdout и stderr) выполнения cmd в оболочке.
Аналогично
getstatusoutput(), за исключением того, что код выхода игнорируется, а возвращаемое значение — строка, содержащая вывод команды. Пример:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'Доступность: POSIX & Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows
8. Примечания
8.1. Преобразование последовательности аргументов в строку в Windows
В Windows последовательность args преобразуется в строку, которая может быть обработана по следующим правилам (которые соответствуют правилам, используемым MS C runtime):
- Аргументы разделяются пробелами, которые являются либо пробелами, либо табуляцией.
- Строка, окружённая двойными кавычками, интерпретируется как один аргумент, независимо от содержащихся в ней пробелов. Цитатная строка может быть встроена в аргумент.
- Двойная кавычка, предшествуемая обратной косой чертой, интерпретируется как буквальная двойная кавычка.
- Обратные косые черты интерпретируются буквально, за исключением случаев, когда они непосредственно предшествуют двойной кавычке.
- Если обратные косые черты непосредственно предшествуют двойной кавычке, каждая пара обратных косых черт интерпретируется как буквальная обратная косая черта. Если количество обратных косых черт нечётное, последняя обратная косая черта экранирует следующую двойную кавычку, как описано в правиле 3.
См. также
-
shlex - Модуль, предоставляющий функции для разбора и экранирования командных строк.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/subprocess.html