Вставьте нажатия клавиш в консоль Linux из Python - PullRequest
7 голосов
/ 30 апреля 2011

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

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

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

Редактировать: Благодаря глупой удаче, я только недавно обнаружил, чтоВерсия PExpect для SVN имеет pexpect.screen .Тем не менее, он не имеет никакого способа запустить программу под ним.Мне придется следить за его развитием.

Ответы [ 2 ]

3 голосов
/ 01 июля 2012

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

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

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

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

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

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

0 голосов
/ 30 апреля 2011

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

...