Управление системными командами в скриптах Python

Раздел: Администрирование -> Системные вызовы

Выполнение команд в Python: обзор возможностей

Python предоставляет несколько способов выполнения системных команд. Выбор зависит от задачи: нужно ли получить вывод, обработать ошибки, выполнить сложную цепочку команд. Рассмотрим наиболее популярные подходы.

Основное решение: subprocess.run

Модуль subprocess является современным и предпочтительным способом запуска дочерних процессов. Функция subprocess.run позволяет выполнить команду, дождаться её завершения и получить объект с результатами.

import subprocess

result = subprocess.run(['ls', '-la'], capture_output=True, text=True)
print('stdout:', result.stdout)
print('stderr:', result.stderr)
print('return code:', result.returncode)

Python os environ (переменные окружения os.environ в python)

Пояснение: передача команды в виде списка аргументов (без shell=True) повышает безопасность. Параметр capture_output захватывает stdout и stderr, text=True возвращает строки вместо байтов.

Типичные ошибки:

  • Забыли указать полный путь к программе или программа не в PATH.
  • При использовании shell=True и неправильном экранировании возможны проблемы безопасности.
  • Необработанные нестандартные коды завершения.

Как выполнить команду и забыть о результате?

Для простого запуска без захвата вывода подходит os.system.

import os
os.system('echo Hello')

Python os getenv (получение переменной окружения os.getenv в python)

Проблемы: код возврата теряется, вывод не сохраняется, подвержен инъекциям.

Не рекомендуется для новых проектов из-за ограниченной функциональности.

Как получить вывод команды построчно?

Можно использовать subprocess.Popen с pipe.

import subprocess

proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
out, _ = proc.communicate(input='строка для передачи')
print(out)

Python os listdir (список файлов в директории os.listdir в python)

Этот способ даёт больше контроля, но требует ручного управления потоками.

Опасность дедлока при неправильном чтении pipe без communicate.

Как выполнить команду с тайм-аутом?

У subprocess.run есть параметр timeout.

try:
    result = subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired:
    print('Процесс превысил время')

При срабатывании тайм-аута процесс завершается.

- Python start exe file (запуск исполняемого файла из python)
- Python имя компьютера (имя компьютера в python)
- Python выполнение команды (выполнение команд в python)

Расширенные примеры выполнения команд

1. Работа с окружением и текущим каталогом

Пример
import subprocess
import os

# Запуск с изменённым окружением
env = os.environ.copy()
env['MY_VAR'] = 'value'
result = subprocess.run(['env'], env=env, capture_output=True, text=True)
print(result.stdout)
...
MY_VAR=value
...

2. Передача данных через stdin и получение результата

Пример
proc = subprocess.Popen(['grep', 'error'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
out, err = proc.communicate(input='line1\nline with error\nline3')
print('matched:', out)
matched: line with error

3. Асинхронное выполнение команды

Пример
import asyncio

async def run_cmd():
    proc = await asyncio.create_subprocess_exec(
        'ls', '-la',
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )
    stdout, stderr = await proc.communicate()
    print(stdout.decode())

asyncio.run(run_cmd())

4. Запуск цепочки команд с конвейером

Пример
# Эмуляция ls | grep py
p1 = subprocess.Popen(['ls'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'py'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
output = p2.communicate()[0]
print(output.decode())
example.py
script.py

5. Безопасное выполнение команды с shell=True с помощью shlex

Пример
import shlex
import subprocess

cmd = 'echo "Hello $USER"'
args = shlex.split(cmd)
result = subprocess.run(args, capture_output=True, text=True)
print(result.stdout)
Hello $USER

Выполнение команд в Python - comments

En
Python выполнение команды (python)