Документация Python неофициальный перевод
Содержание страницы

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

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

os.system
os.spawn*

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

См. также

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

Использование модуля подпроцессUsing the subprocess Module

Этот модуль определяет один класс с именем Popen:

class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

Аргументы:

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

В Unix с shell=False (по умолчанию): В этом случае класс Popen использует os.execvp() для выполнения дочерней программы. args обычно должен быть последовательностью. Строка будет рассматриваться как последовательность, содержащая эту строку в качестве единственного элемента (программы для выполнения).

В Unix с shell=True: Если args – строка, она задаёт командную строку для выполнения через оболочку. Если args является последовательностью, первый элемент задаёт командную строку, а любые дополнительные элементы будут рассматриваться как дополнительные аргументы оболочки.

В Windows: класс Popen использует CreateProcess() для выполнения дочерней программы, которая работает со строками. Если args – последовательность, она будет преобразована в строку с помощью метода list2cmdline(). Обратите внимание, что не все приложения MS Windows интерпретируют командную строку одинаково: list2cmdline() предназначен для приложений, использующих те же правила, что и среда выполнения MS C.

bufsize, если задан, имеет тот же смысл, что и соответствующий аргумент встроенной функции open(): 0 – без буферизации, 1 – построчная буферизация, любое другое положительное значение означает использование буфера (примерно) такого размера. Отрицательное bufsize означает использование системного значения по умолчанию, что обычно означает полную буферизацию. Значение по умолчанию для bufsize0 (без буферизации).

Аргумент executable задаёт программу для выполнения. Он требуется очень редко: обычно программа для выполнения определяется аргументом args. Если shell=True, аргумент executable указывает, какую оболочку использовать. В Unix оболочкой по умолчанию является /bin/sh. В Windows оболочка по умолчанию задаётся переменной окружения COMSPEC.

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

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

Если close_fds равен true, все файловые дескрипторы, кроме 0, 1 и 2, будут закрыты перед выполнением дочернего процесса. (Только Unix). Или, в Windows, если close_fds равен true, то дочерний процесс не унаследует ни одного дескриптора. Обратите внимание: в Windows нельзя одновременно установить close_fds в true и перенаправлять стандартные дескрипторы с помощью stdin, stdout или stderr.

Если shell равен True, указанная команда будет выполняться через оболочку.

Если cwd не равен None, текущий каталог дочернего процесса будет изменён на cwd перед его выполнением. Обратите внимание, что этот каталог не учитывается при поиске исполняемого файла, поэтому нельзя указать путь к программе относительно cwd.

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

Если universal_newlines равен True, файловые объекты stdout и stderr открываются как текстовые файлы, но строки могут завершаться любым из символов: '\n' (соглашение Unix), '\r' (соглашение старых Macintosh) или '\r\n' (соглашение Windows). Все эти внешние представления воспринимаются программой Python как '\n'.

Примечание

Эта возможность доступна только в том случае, если Python собран с поддержкой универсальных символов новой строки (по умолчанию). Кроме того, атрибут newlines файловых объектов stdout, stdin и stderr не обновляется методом communicate().

Параметры startupinfo и creationflags, если они заданы, будут переданы базовой функции CreateProcess(). Они могут задавать такие вещи, как внешний вид главного окна и приоритет нового процесса. (Только в Windows)

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

Вспомогательные функцииConvenience Functions

Этот модуль также определяет четыре вспомогательные функции:

subprocess.call(*popenargs, **kwargs)

Запускает команду с аргументами. Ожидает завершения команды, затем возвращает атрибут returncode.

Аргументы такие же, как у конструктора Popen. Пример:

retcode = call(["ls", "-l"])
subprocess.check_call(*popenargs, **kwargs)

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

Аргументы такие же, как у конструктора Popen. Пример:

check_call(["ls", "-l"])
subprocess.getstatusoutput(cmd)
Return ``(status, output)`` of executing *cmd* in a shell.

Выполняет строку cmd в оболочке с помощью os.popen() и возвращает кортеж из двух элементов (status, output). cmd фактически выполняется как { cmd ; } 2>&1, так что возвращаемый вывод будет содержать сообщения вывода или ошибок. Конечный символ новой строки удаляется из вывода. Код завершения команды можно интерпретировать в соответствии с правилами для функции C wait. Пример:

>>> import subprocess
>>> 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')

Доступность: UNIX.

subprocess.getoutput(cmd)
Return output ``(stdout or stderr)`` of executing *cmd* in a shell.

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

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

Доступность: UNIX.

ИсключенияExceptions

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

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

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

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

БезопасностьSecurity

В отличие от некоторых других функций popen, данная реализация никогда не вызывает /bin/sh неявно. Это означает, что все символы, включая метасимволы оболочки, могут безопасно передаваться дочерним процессам.

Объекты PopenPopen Objects

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

Popen.poll()
Проверяет, завершён ли дочерний процесс. Устанавливает и возвращает атрибут returncode.
Popen.wait()

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

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

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

Popen.communicate(input=None)

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

communicate() возвращает кортеж (stdoutdata, stderrdata).

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

Примечание

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

Popen.send_signal(signal)

Отправляет сигнал signal дочернему процессу.

Примечание

В Windows на данный момент поддерживается только SIGTERM. Это псевдоним для terminate().

Popen.terminate()
Останавливает дочерний процесс. В ОС Posix метод отправляет SIGTERM дочернему процессу. В Windows для остановки дочернего процесса вызывается функция Win32 API TerminateProcess.
Popen.kill()
Завершает дочерний процесс. В ОС POSIX функция отправляет дочернему процессу сигнал SIGKILL. В Windows kill() – это псевдоним для terminate().

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

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

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

Popen.stdin
Если аргумент stdin был PIPE, то этот атрибут представляет собой файловый объект, который передаёт входные данные дочернему процессу. В противном случае он равен None.
Popen.stdout
Если аргумент stdout был PIPE, то этот атрибут представляет собой файловый объект, содержащий вывод дочернего процесса. В противном случае он равен None.
Popen.stderr
Если аргумент stderr был PIPE, то этот атрибут представляет собой файловый объект, содержащий сообщения об ошибках дочернего процесса. В противном случае он равен None.
Popen.pid
PID дочернего процесса.
Popen.returncode

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

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

Замена устаревших функций модулем подпроцессReplacing Older Functions with the subprocess Module

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

Примечание

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

В следующих примерах предполагается, что модуль подпроцесс импортирован с помощью «from subprocess import *».

Замена обратного апострофа оболочки /bin/shReplacing /bin/sh shell backquote

output=`mycmd myarg`
==>
output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]

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

output=`dmesg | grep hda`
==>
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

Замена os.system()Replacing os.system()

sts = os.system("mycmd" + " myarg")
==>
p = Popen("mycmd" + " myarg", shell=True)
sts = os.waitpid(p.pid, 0)

Примечания:

  • Вызов программы через оболочку обычно не требуется.
  • Проще смотреть на атрибут returncode, чем на код завершения.

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

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.spawnReplacing the os.spawn family

Пример P_NOWAIT:

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

Пример P_WAIT:

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

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

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

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

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

Замена os.popenReplacing os.popen

pipe = os.popen(cmd, 'r', bufsize)
==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
pipe = os.popen(cmd, 'w', bufsize)
==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin