> **Источник:** https://python-all.ru/3.0/library/subprocess.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

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

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

```python
os.system
os.spawn*
```

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

> **См. также**
>
> [**PEP 324**](https://python-all.ru/3.0/library/subprocess.html) – PEP, предлагающий модуль подпроцесса

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

Этот модуль определяет один класс с именем [`Popen`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen):

#### `[subprocess.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()`](https://python-all.ru/3.0/library/os.html#os.execvp) для выполнения дочерней программы. *args* обычно должен быть последовательностью. Строка будет рассматриваться как последовательность, содержащая эту строку в качестве единственного элемента (программы для выполнения).

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

В Windows: класс [`Popen`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen) использует CreateProcess() для выполнения дочерней программы, которая работает со строками. Если *args* – последовательность, она будет преобразована в строку с помощью метода `list2cmdline()`. Обратите внимание, что не все приложения MS Windows интерпретируют командную строку одинаково: `list2cmdline()` предназначен для приложений, использующих те же правила, что и среда выполнения MS C.

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

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

*stdin*, *stdout* и *stderr* задают дескрипторы файлов стандартного ввода, стандартного вывода и стандартного вывода ошибок выполняемой программы соответственно. Допустимые значения: [`PIPE`](https://python-all.ru/3.0/library/subprocess.html#subprocess.PIPE), существующий файловый дескриптор (положительное целое число), существующий файловый объект и `None`. [`PIPE`](https://python-all.ru/3.0/library/subprocess.html#subprocess.PIPE) означает, что должен быть создан новый канал к дочернему процессу. При `None` перенаправления не происходит; дескрипторы файлов дочернего процесса наследуются от родительского. Кроме того, *stderr* может быть [`STDOUT`](https://python-all.ru/3.0/library/subprocess.html#subprocess.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`](https://python-all.ru/3.0/library/constants.html#True), указанная команда будет выполняться через оболочку.

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

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

Если *universal\_newlines* равен [`True`](https://python-all.ru/3.0/library/constants.html#True), файловые объекты stdout и stderr открываются как текстовые файлы, но строки могут завершаться любым из символов: `'\n'` (соглашение Unix), `'\r'` (соглашение старых Macintosh) или `'\r\n'` (соглашение Windows). Все эти внешние представления воспринимаются программой Python как `'\n'`.

> **Примечание**
>
> Эта возможность доступна только в том случае, если Python собран с поддержкой универсальных символов новой строки (по умолчанию). Кроме того, атрибут newlines файловых объектов [`stdout`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.stdout), [`stdin`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.stdin) и [`stderr`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.stderr) не обновляется методом [`communicate()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.communicate).

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

#### `[subprocess.PIPE]subprocess.PIPE`

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

*stdin*

,

*stdout*

или

*stderr*

для

[`Popen`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen)

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

#### `[subprocess.STDOUT]subprocess.STDOUT`

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

*stderr*

для

[`Popen`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen)

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

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

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

#### `[subprocess.call]subprocess.call(*popenargs, **kwargs)`

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

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

```python
retcode = call(["ls", "-l"])
```

#### `[subprocess.check_call]subprocess.check_call(*popenargs, **kwargs)`

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

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

```python
check_call(["ls", "-l"])
```

#### `[subprocess.getstatusoutput]subprocess.getstatusoutput(cmd)`

#### `` Return ``(status, output)`` of executing *cmd* in a shell. ``

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

```python
>>> 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]subprocess.getoutput(cmd)`

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

Аналогично [`getstatusoutput()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.getstatusoutput), за исключением того, что код возврата игнорируется, а возвращаемое значение – строка, содержащая вывод команды. Пример:

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

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

### Исключения

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

Наиболее часто возбуждаемым исключением является [`OSError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.OSError). Оно возникает, например, при попытке выполнить несуществующий файл. Приложения должны быть готовы к исключениям [`OSError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.OSError).

Исключение [`ValueError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.ValueError) будет возбуждено, если [`Popen`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen) вызван с недопустимыми аргументами.

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

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

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

## Объекты Popen

Экземпляры класса [`Popen`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen) имеют следующие методы:

#### `[subprocess.Popen.poll]Popen.poll()`

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

[`returncode`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.returncode)

.

#### `[subprocess.Popen.wait]Popen.wait()`

Ожидает завершения дочернего процесса. Устанавливает и возвращает атрибут [`returncode`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.returncode).

> **Предупреждение**
>
> Это приведет к взаимной блокировке, если дочерний процесс создаст достаточно выходных данных для канала stdout или stderr, так что он заблокируется в ожидании, пока буфер канала ОС не сможет принять больше данных. Используйте [`communicate()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.communicate), чтобы избежать этого.

#### `[subprocess.Popen.communicate]Popen.communicate(input=None)`

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

[`communicate()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.communicate) возвращает кортеж `(stdoutdata, stderrdata)`.

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

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

#### `[subprocess.Popen.send_signal]Popen.send_signal(signal)`

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

> **Примечание**
>
> В Windows на данный момент поддерживается только SIGTERM. Это псевдоним для [`terminate()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.terminate).

#### `[subprocess.Popen.terminate]Popen.terminate()`

Останавливает дочерний процесс. В ОС Posix метод отправляет SIGTERM дочернему процессу. В Windows для остановки дочернего процесса вызывается функция Win32 API

`TerminateProcess`

.

#### `[subprocess.Popen.kill]Popen.kill()`

Завершает дочерний процесс. В ОС POSIX функция отправляет дочернему процессу сигнал SIGKILL. В Windows

[`kill()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.kill)

– это псевдоним для

[`terminate()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.terminate)

.

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

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

#### `[subprocess.Popen.stdin]Popen.stdin`

Если аргумент

*stdin*

был

[`PIPE`](https://python-all.ru/3.0/library/subprocess.html#subprocess.PIPE)

, то этот атрибут представляет собой файловый объект, который передаёт входные данные дочернему процессу. В противном случае он равен

`None`

.

#### `[subprocess.Popen.stdout]Popen.stdout`

Если аргумент

*stdout*

был

[`PIPE`](https://python-all.ru/3.0/library/subprocess.html#subprocess.PIPE)

, то этот атрибут представляет собой файловый объект, содержащий вывод дочернего процесса. В противном случае он равен

`None`

.

#### `[subprocess.Popen.stderr]Popen.stderr`

Если аргумент

*stderr*

был

[`PIPE`](https://python-all.ru/3.0/library/subprocess.html#subprocess.PIPE)

, то этот атрибут представляет собой файловый объект, содержащий сообщения об ошибках дочернего процесса. В противном случае он равен

`None`

.

#### `[subprocess.Popen.pid]Popen.pid`

PID дочернего процесса.

#### `[subprocess.Popen.returncode]Popen.returncode`

Код возврата дочернего процесса, устанавливаемый методами [`poll()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.poll) и [`wait()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.wait) (а косвенно и [`communicate()`](https://python-all.ru/3.0/library/subprocess.html#subprocess.Popen.communicate)). Значение `None` указывает, что процесс ещё не завершён.

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

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

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

> **Примечание**
>
> Все функции в этом разделе (более или менее) молча завершаются ошибкой, если выполняемая программа не может быть найдена; этот модуль вызывает исключение [`OSError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.OSError).

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

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

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

### Замена конвейера оболочки

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

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

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

Примечания:

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

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

```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"])
```

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

```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, 'r', bufsize)
==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
```

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