Pexpect – автоматизация терминала

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

Автоматизация взаимодействия с командной строкой необходима во множестве задач: от управления удалёнными серверами до автоматизированного тестирования CLI-интерфейсов. Когда команды требуют интерактивного ввода или ожидания вывода, стандартные средства вроде subprocess становятся неэффективными. В таких случаях на помощь приходит Pexpect.

Pexpect — мощная библиотека Python для автоматизации управления интерактивными приложениями. Она позволяет запускать процессы, отслеживать их вывод, реагировать на приглашения (prompts), и программно отправлять ввод, имитируя поведение пользователя.

В этой статье мы разберём структуру, принципы работы, все ключевые методы библиотеки Pexpect, и приведём практические кейсы автоматизации.

Основная часть

Установка и подключение

pip install pexpect

Импорт:

import pexpect

Как работает Pexpect

Pexpect создаёт дочерний процесс, перехватывает его stdout/stderr и реагирует на определённые шаблоны (например, текст приглашения к вводу). Это позволяет автоматизировать:

  • Вход по SSH

  • Управление FTP

  • Автоматизацию bash-команд

  • Взаимодействие с CLI-приложениями

  • Обход систем с паролями и авторизацией

Основной класс: spawn

Создание процесса

child = pexpect.spawn("ssh user@host")

Важные параметры:

  • encoding="utf-8" — обязательно для работы со строками

  • timeout=30 — время ожидания вывода

  • logfile=sys.stdout — логгирование процесса

Ожидание вывода

child.expect("password:")
child.sendline("my_password")

Чтение и запись

child.sendline("ls -la")
child.expect(pexpect.EOF)
print(child.before)

Методы класса spawn

Метод Назначение
expect(pattern) Ожидает строку, соответствующую шаблону
sendline(text) Отправляет строку + перенос строки
send(text) Отправляет строку без переноса
before Текст до совпадения шаблона
after Текст совпавший с шаблоном
read() / readline() Чтение вывода
isalive() Проверка, активен ли процесс
close() Завершает процесс
expect_exact() Точное совпадение без регулярных выражений
expect_list() Ждёт одно из нескольких шаблонов
expect([list]) Перебор нескольких выражений с индексом совпадения

Работа с шаблонами и регулярками

Pexpect позволяет использовать мощные регулярные выражения:

child.expect(r"Password.*:")

Также можно передавать список выражений:

index = child.expect(["Login successful", "Permission denied"])
if index == 0:
    print("Success")
else:
    print("Failure")

Обработка ошибок и таймаутов

try:
    child.expect("#", timeout=10)
except pexpect.TIMEOUT:
    print("Timeout error")
except pexpect.EOF:
    print("Process ended")

Контроль вывода

child.logfile = open("session.log", "wb")

Функция run() для простых задач

output, exitstatus = pexpect.run("ls -l", withexitstatus=True)
print(output)

Используется для простых однокомандных сценариев без интерактивности.

Подключение по SSH (пример)

import pexpect

child = pexpect.spawn("ssh user@192.168.0.1", encoding='utf-8')
child.expect("password:")
child.sendline("my_password")
child.expect("#")
child.sendline("ls /home")
child.expect("#")
print(child.before)

Работа с sudo

child = pexpect.spawn("sudo apt update", encoding='utf-8')
child.expect("password for")
child.sendline("my_sudo_pass")
child.expect(pexpect.EOF)
print(child.before)

Запись макросов

Pexpect можно использовать для создания автоматизированных макросов, например, для управления bash-скриптами или UI через терминал.

Интеграция с CI/CD

Pexpect может автоматически управлять CLI-интерфейсами в GitLab CI, Jenkins, GitHub Actions.

script:
  - python deploy_script.py

Ключевые кейсы применения

  • Автоматизация SSH и SCP

  • Запуск команд с авторизацией

  • Тестирование CLI-приложений

  • Отладка сетевых взаимодействий

  • Программное взаимодействие с командной строкой

Плюсы и минусы

Преимущества:

  • Гибкость и контроль

  • Поддержка regex

  • Поддержка логирования и отладка

  • Простота интеграции в пайплайны

Ограничения:

  • Не кроссплатформенен полностью (нужен POSIX)

  • Не подходит для GUI

  • Чувствительность к форматированию CLI

Полный список функций и методов Pexpect с пояснениями

1. pexpect.spawn(command, args=[], **kwargs)

Создаёт и запускает дочерний процесс.

Параметры:

  • command: строка команды (например, 'ssh user@host')

  • args: список дополнительных аргументов

  • timeout: время ожидания ответа (по умолчанию 30)

  • encoding: кодировка (например, 'utf-8')

  • logfile: поток для логирования вывода

  • echo: выводить ли обратно введённые данные

Пример:

python
child = pexpect.spawn('ssh user@host')

2. .expect(pattern, timeout=-1, searchwindowsize=None, async_=False)

Ожидает появление текста (или шаблона) во вводе. Самый используемый метод.

Параметры:

  • pattern: строка, список строк или регулярное выражение

  • timeout: максимум времени ожидания

  • searchwindowsize: размер окна поиска (для больших буферов)

  • async_: асинхронный режим (True / False)

Пример:

python
child.expect('password:')

3. .expect_exact(pattern_list, timeout=-1)

Как expect(), но ищет точное совпадение без использования регулярных выражений.

Пример:

python
child.expect_exact(['continue', 'abort'])

4. .sendline(s='')

Отправляет строку (и символ новой строки \n).

Пример:

python
child.sendline('ls -la')

5. .send(s)

Отправляет строку без символа новой строки.

Пример:

python
child.send('yes')

6. .read()

Считывает весь оставшийся вывод процесса до EOF.

Пример:

python
output = child.read()

7. .readline()

Считывает одну строку вывода.


8. .read_nonblocking(size=1, timeout=-1)

Неблокирующее чтение из stdout дочернего процесса.


9. .readlines()

Считывает все строки до конца.


10. .close()

Закрывает процесс (отправляет EOF и убивает, если не завершился).


11. .isalive()

Возвращает True, если дочерний процесс всё ещё работает.


12. .wait()

Ожидает завершения процесса и возвращает его exitstatus.


13. .terminate(force=False)

Прерывает процесс. Если force=True, убивает его принудительно (SIGKILL).


14. .kill(signal)

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

Пример:

python
import signal child.kill(signal.SIGINT)

15. .expect_list(patterns, timeout=-1, searchwindowsize=None, async_=False)

Ожидает первое совпадение из списка шаблонов, возвращает индекс найденного шаблона.


16. .expect_exact_list(patterns, timeout=-1)

То же самое, но для точного сопоставления.


17. .expect_loop(callback)

Выполняет цикл ожидания, передавая события в колбэк-функцию.


18. .interact(escape_character=chr(29), input_filter=None, output_filter=None)

Переходит в интерактивный режим (пользователь управляет процессом вручную).

Пример:

python
child.interact()

19. .before

Содержит вывод до последнего expect.


20. .after

Содержит совпавший шаблон после expect.


21. .match

Возвращает объект совпадения (если использовались регулярные выражения).


22. .buffer

Содержит внутренний буфер.


23. .eof()

Возвращает True, если дочерний процесс достиг EOF.


24. .terminate(force=False)

Аналог close, но явно отправляет сигнал SIGTERM или SIGKILL.


25. .spawn.read_child()

Считывает из канала stdout дочернего процесса. Используется внутри expect.


26. pexpect.run(command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None)

Упрощённая функция для запуска процесса и получения вывода.

Пример:

python
output = pexpect.run('ls -l')

27. pexpect.TIMEOUT

Исключение, выбрасываемое при превышении таймаута.


28. pexpect.EOF

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


29. pexpect.ExceptionPexpect

Базовый класс всех исключений Pexpect.


30. pexpect.replwrap.REPLWrapper

Отдельный инструмент для работы с интерактивными оболочками (Python REPL, bash и т.д.).

Пример:

python
from pexpect.replwrap import REPLWrapper python = REPLWrapper("python3", ">>> ", None) result = python.run_command("1 + 1") print(result)

Заключение

Pexpect — мощный инструмент для тех, кто работает с терминалами, серверами и командной строкой. Он позволяет автоматизировать диалоги, обрабатывать интерактивные запросы, управлять сессиями и строить интеллектуальные скрипты CLI-взаимодействия. Эта библиотека идеальна для DevOps-инженеров, разработчиков и QA, которым важно контролировать каждый байт вывода в консоли.