Вставка нажатий клавиш в консоль Linux из Python

недавно я столкнулся с довольно странной задачей, одним из результатов которой является необходимость использования тонов DTMF (он же "сенсорный тон") для управления терминалом компьютера Не-X Linux. Компьютер имеет модем, к которому можно получить доступ через ALSA, и, следовательно, программу Sox "rec", через которую я читаю вход. В противном случае компьютер полностью изолирован, не имеет Ethernet или других сетевых интерфейсов. Реализация алгоритма Гертцеля I am использование работает очень хорошо,как и механизм синтеза речи eSpeak, который является единственным источником вывода; это должно работать с любым сенсорным телефоном. Он считывает оба входа (вход-восьмеричные цифры, по одному байту ASCII за раз) и независимо от dash shell подает назад -- приглашение, вывод из команд и т. д., использование мнемоники ASCII для управляющих символов.

текущий метод, который я использую для взаимодействия с dash и программы, запущенные через него, являются pexpect модуль. Однако мне нужно, чтобы он мог, по требованию, прочитать все содержимое строки, на которой расположен курсор, и я не помню pexpect будучи в состоянии сделать это (если это так, я не могу сказать.). Единственное другое решение, которое я могу придумать, - это каким-то образом использовать Python для управления или действовать как драйверы клавиатуры и консоли.

действительно ли это единственный способ сделать это (и если да, то возможно ли это с Python?), или есть другой способ прямой доступ к содержимому консоли?

Edit: благодаря немой удаче, я недавно обнаружил, что версия SVN PExpect имеет pexpect.экран. Однако у него нет никакого способа фактически запустить программу под ним. Я должен следить за его развитием.

2 ответов


простое решение-использовать интерфейс uinput ядра Linux. Он позволяет вставлять нажатия клавиш и события мыши в ядро, точно так же, как если бы они исходили от физического устройства человеческого интерфейса. Это в основном превратит ваше приложение в клавиатуру / мышь.

поскольку вы работаете с Python, я рекомендую вам взглянуть на python-uinput модуль.

Если вам удобно с двоичным вводом-выводом в Python, то вы, безусловно, можете сделать то же самое без каких-либо библиотек; просто проверьте /usr/include/linux/uinput.h заголовочный файл для соответствующих структур (интерфейс полностью стабилен), и, возможно, некоторых uinput уроки в C тоже.

обратите внимание, что доступ к /dev/uinput или /dev/input/uinput устройство (в зависимости от вашего дистрибутива) обычно требует привилегий root. Я бы лично запустил службу Python как пользователь и группа, посвященная службе, и изменил / добавил правило udev (проверьте все файлы в rules.d), чтобы позволить чтение-запись доступа к устройству uinput в эту группу, что-то вроде

SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
KERNEL=="uinput", MODE="0660", GROUP="the-dedicated-group"

однако, если ваше приложение Python просто выполняет программы, вы должны сделать его эмулятором терминала - например, используя этой. Вы также можете сделать это без каких-либо дополнительных библиотек, используя Python pty; основная работа заключается в том, чтобы имитировать терминал с escape-последовательностями ANSI, чтобы приложения не путались, а существующие эмуляторы терминалов имеют такие код.


Если вы хотите управлять содержимым консоли, вы, вероятно, хотите использовать curses. Это хорошо документировано здесь. Посмотреть window.getch() и window.getyx().