Создайте команду, поместив строку в tty

Мне удалось это сделать

  echo -n " command "> / dev / tty1 

Буквы появляются, а курсор перемещается, но они являются «призраками» – если вы нажмете Enter , ничего не происходит (они не находятся в stdin).

Редактировать:

В середине нижеприведенного скриншота вы видите, почему я вижу использование этого. (Строка с красной надписью, прямо под строкой с желтой надписью.) Как и сейчас, вы на самом деле не редактируете текст заметки; вам просто предлагается написать новый текст, который заменит текст примечания, которое вы (на самом деле) не редактируете. Таким образом, я думал, что это можно исправить, просто вставив старый текст в tty: если пользователь нажимает Enter, модификация не производится. (Эта программа находится в Perl / MySQL, но я подумал, что было бы более интересно просить общее решение, чем «как это сделать в Perl».)

пример

Изменить 2:

Вот код Perl, который использует код C ниже (работает точно так, как предполагалось), а также новый скриншот – надеюсь, это прояснит все без сомнения 🙂 Еще раз посмотрим на середину скриншота, где сделано редактирование к тексту заметки – на этот раз старый текст есть, например, если вы просто хотите исправить опечатку, вам не нужно будет перепечатывать весь текст заметки.

my $edit_note_text = $edit_note_data[2]; print BOLD, RED, " new text: ", RESET; system("writevt /dev/tty \"$edit_note_text\""); my $new_text = <$in>; $new_text = fix_input($new_text); my $set_text = "UPDATE notes SET note = \"$new_text\" WHERE id = $edit_note_id"; $db->do($set_text); 

better_example

4 Solutions collect form web for “Создайте команду, поместив строку в tty”

Я только что нашел небольшую программу C, называемую writevt которая делает трюк. Возьмите здесь исходный код. Чтобы скомпилировать gcc сначала удалите следующие строки:

 #include <lct/cline.h> #include <lct/utils.h> 

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

Применение:

 sudo writevt /dev/ttyN command 

Обратите внимание, что по какой-то причине вам нужно использовать '\r' (или '\x0D' ) вместо '\n' (или '\x0A' ) для отправки возврата.

Терминал удваивается как две вещи: устройство ввода (например, клавиатура) и устройство отображения (например, монитор). Когда вы читаете с терминала, вы получаете то, что исходит от устройства ввода. Когда вы пишете на терминал, данные поступают на устройство отображения.

Нет общего способа принудительного ввода в терминал. Это редко бывает необходимо. Если вам нужно взаимодействовать с программой, для которой требуется терминал, используйте специальный эмулятор терминала, такой как Expect или Empty , или программируемую оболочку терминала, такую ​​как Screen или Tmux . Вы можете принудительно ввести вход в консоль Linux с помощью ioctl . Вы можете принудительно ввести в эмулятор терминала X11 такие инструменты, как xdotool или xmacro .

По крайней мере, Linux и BSD имеют TIOCSTI ioctl для перевода символов обратно в буфер ввода терминала (до предела [4096 символов в Linux]):

 #include <sys/ioctl.h> #include <termios.h> #include <stdio.h> #include <stdlib.h> void stackchar(char c) { if (ioctl(0, TIOCSTI, &c) < 0) { perror("ioctl"); exit(1); } } int main(int argc, char *argv[]) { int i, j; char c; for (i = 1; i < argc; i++) { if (i > 1) stackchar(' '); for (j=0; (c = argv[i][j]); j++) { stackchar(c); } } exit(0); } 

Скомпилируйте его и назовите его как:

 cmd foo bar < "$some_tty" 

нажимать символы на какой-то tty.

И в perl:

 require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV; 

Изменить : я понимаю, что это то же самое, что и в решении writevt . Комментарий и название команды вводят в заблуждение, поскольку TIOCSTI работает для любого терминала, а не только для VT.

У меня есть более полная демонстрация на Stack Overflow .

В python вы можете:

 import fcntl import sys import termios with open('/dev/tty1', 'w') as fd: for char in "ls -la\n": fcntl.ioctl(fd, termios.TIOCSTI, char) 

Это предполагает простое "command" значение ls -la и использование пути tty, указанного OP.

  • Вызывать команду / сценарий, отключенный от управляющего терминала?
  • Почему мои виртуальные консоли полностью пустые?
  • Сочетание тройника и tty
  • Псевдотерминал не будет выделен, поскольку stdin не является терминалом
  • Как работает терминал Linux?
  • Почему showconsolefont имеет разные выходные данные в tmux?
  • Каковы обязанности каждого компонента Pseudo-Terminal (PTY) (программное обеспечение, ведущая сторона, подчиненная сторона)?
  • Начать процесс на другом tty
  • RS485: ioctl: ttyS1 не tty устройство
  • Могу ли я изменить шрифт терминала?
  • Как найти, какой последовательный порт используется?
  • Linux и Unix - лучшая ОС в мире.