Как получить вывод из subprocess.call() в Python: решение

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если вам необходимо выполнить захват вывода команды, рекомендую использовать функцию subprocess.run() с указанным параметром capture_output=True. Пример использования функции представлен ниже:

Python
Скопировать код
import subprocess
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
output = result.stdout  # Здесь сохраняется вывод команды
error = result.stderr  # Здесь сохраняются ошибки, если таковые имеются

В результате выполнения данного кода вывод команды будет сохранён в переменной output, а возникшие ошибки – в error.

Кинга Идем в IT: пошаговый план для смены профессии

Детальное изучение: понимание и поиск альтернатив

Выбор подходящей функции для задачи

Есть множество инструментов, подходящих для выполнения различных задач. Хотя subprocess.run() может быть универсальным решением, для определенных задач эффективней оказывается использование subprocess.Popen() с указанным аргументом stdout=subprocess.PIPE. Ваш выбор должен зависеть от сложности выполняемой задачи и используемой версии Python.

Python
Скопировать код
import subprocess
with subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, text=True) as proc:
    output, _ = proc.communicate()  # Процесс захватывает вывод

Выявление ошибок

Ошибки – это неотъемлемая часть программирования, которую невозможно игнорировать. Если вы указываете вместе stderr=subprocess.PIPE и stdout, то в таком случае Python будет выявлять ошибки вместе с отслеживанием вывода.

Python
Скопировать код
result = subprocess.run(['ls', '-la'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(f"Вывод: {result.stdout}")
print(f"Ошибка: {result.stderr if result.stderr else 'Ошибок нет.'}")

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

Разные системы предполагают разные подходы к выполнению задач, и здесь может пригодиться shlex.split(), позволяющий корректно обрабатывать командные строки для разных платформ.

Python
Скопировать код
import shlex, subprocess
command = shlex.split("ls -la")
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)

Декодирование вывода

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

Правильный выбор инструмента

Важно внимательно смотреть при выборе подходящих инструментов! subprocess.call() улавливает статус выполнения процесса как археолог – артефакты, тогда как subprocess.run() и subprocess.check_output() подробно фиксируют информацию о выводе.

Визуализация

Можно представить работу subprocess.call() как трубу в водопроводе (🚰), где вода – это процесс.

Markdown
Скопировать код
subprocess.call(args, ...)
         |
         |   (вывод)
         V
Ведро (🪣)

Здесь ведро (🪣) собирает статус выполнения.

Markdown
Скопировать код
В отличие от ведра, текстовый вывод (🗨️) лучше собирать с помощью более впитывающего объекта:
subprocess.check_output(args, ...)
         |
         |   (текстовый вывод 🗨️)
         V
Губка (🧽)

Губка (🧽) поглощает текстовый вывод с помощью subprocess.check_output().

Хитрости, советы и решения, вызывающие восклицания "Ааа, вот так!"

Подготовка ко всем сценариям

Ошибки случаются, и Python предусматривает такие случаи. Для защиты от возможных проблем вы можете использовать subprocess.CalledProcessError, что обеспечит надежную обработку исключений.

Python
Скопировать код
try:
    output = subprocess.check_output(['false_command'], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
    print(f"Произошла ошибка: {e.output}")

Разъяснение недоразумений

Попытка использования StringIO с subprocess.call() для захвата вывода является бессмысленной и не приводит к успеху.

Быстрота и чистота

Старайтесь избегать создания лишних временных файлов при работе с выводом. Вместо этого используйте трубы (pipes) в сочетании с Popen() и communicate(), чтобы ваш код оставался аккуратным и работал эффективно.

Эволюция Python

Не забывайте, что subprocess.run() доступна начиная с Python 3.5. В более ранних версиях используйте проверенный Popen() или более лаконичный check_output().

Полезные материалы

  1. subprocess — Управление подпроцессами — Документация Python 3.12.2 — официальная документация Python по управлению подпроцессами.
  2. python – Сохранение вывода вызова subprocess.Popen в строке – Stack Overflow — обсуждение вопросов сохранения вывода subprocess.Popen в строке.
  3. Применение модуля subprocess для работы с подпроцессами в Python – Real Python — глубокий урок по модулю subprocess.
  4. subprocess — Запуск внешних процессов — PyMOTW 3 — статья с примерами работы с подпроцессами в Python.
  5. Выполнение команд оболочки из Python — гид по выполнению команд оболочки средствами Python.
  6. Объяснение модуля subprocess в Python – GeeksforGeeks — разъяснение модуля subprocess на сайте GeeksforGeeks.
  7. Урок Python: Запуск внешних команд при помощи модуля Subprocess – YouTube — видеоурок о работе с модулем subprocess от Corey Schafer.