С использованиемБаш, как я могу прочитать ответ терминала в переменную без взаимодействия с пользователем? Следующий однострочный код все еще требует Enterнажатия один раз:
echo -ne '\005' && read -s && echo ${REPLY}
Также, как я могу настроитьXtermотправить что-то осмысленное в ответ на ^E
? Пока что единственный эмулятор терминала, который я видел, отправляющий какой-либо ответ, этоШпатлевка.
решение1
Строку ответа можно настроить в xterm с помощьюanswerbackString
ресурс. Этот ресурс был добавлен в1998. Первоначально возвращал "xterm", так как1999По умолчанию используется пустая строка, поскольку некоторые пользователи заметили возможность злоупотребления управляющими последовательностями, которые могут отправить на компьютер неожиданную команду.
Другие терминалы могут всегда возвращать пустую строку (konsole, mlterm, vte). Но rxvt (и rxvt-unicode) возвращают неожиданный ответ: устройство атрибутирует ответ для VT102 (последовательность escape). PuTTY возвращает «PuTTY»(вероятно, из-за раннего влияния xterm).
При быстрой проверке консоль Linux отображает «a» (вероятно, ошибка).
Поскольку оригинальный VT100 предоставлял эту функцию в качестве настраиваемой/конфигурируемой, она была бы ограниченапечатныйсимволы. По этой причине ответ rxvt/urxvt неожиданный. На странице руководства есть неясный комментарий по этому поводу:
answerbackString
:нить
Укажите ответ rxvt-unicode, который отправляет оболочке при передаче символа ENQ (control-E). Он может содержать escape-значения, как описано в записи наkeysym
следующий.
(обещанное описание отсутствует).
Поскольку длина строки ответа неизвестна, приложение, которое ее считывает, должно допускать ожидание (в случае, если символы поступают в более чем одной операции чтения). Конечно, есть специфичная для ksh/bash TMOUT
функция, которая может помочь с shell-скриптингом, наряду с -t
опцией для read
команды. Для общего использования я избегаю этого, используя stty
, например, (см.dynamic.sh
):
stty raw -echo min 0 time 5
временно настроить терминал так, чтобы a read
выходил из строя через 0,5 секунды, и позволить ему вернуться без чтения каких-либо символов. Чтобы увидеть, как сохраняются/восстанавливаются настройки, полезно прочитать скрипт.
Дальнейшее чтение:
- the
vttests
скрипты вxterm
, многие из которых считывают строки ответа терминала. stty
- установить параметры для терминала(POSIX)read
- прочитать строку из стандартного ввода(POSIX)
решение2
Даже при наличии тайм-аута и (некоторого) количества символов для чтения, похоже, bash
( version 4.2.46(1)-release
) не может сохранить REPLY
, здесь путем выдачи управляющей последовательности «Сообщить позицию курсора», сначала с вводом новой строки, а затем ожиданием тайм-аута:
$ echo -ne '\033[6n' && read -n 16 -s -t 3; echo -n $REPLY | xxd
0000000: 1b5b 3234 3b31 52 .[24;1R
$ echo -ne '\033[6n' && read -n 16 -s -t 3; echo -n $REPLY | xxd
$
Проблема здесь в том, что -n
больше, чем число возвращаемых байтов; если -n
же вместо этого точно соответствует нужному размеру или меньше, ответ будет прочитан без необходимости ввода (или тайм-аута). Если вы знаете конечный уникальный символ строки ответа, вы можете получить ответ, разделив "строки" этим символом; для подсказки позиции символа отчета этот разделитель можно взять как R
:
$ echo -ne '\033[6n' && read -n 999 -d R -s; echo -n $REPLY | xxd
0000000: 1b5b 3234 3b31 .[24;1
$
При наличии неизвестных входных данных неизвестной длины вам придется либо подать заявку на ошибку bash
, либо, возможно, утомительно откусывать байты один за другим, пока не сработает тайм-аут:
$ out="got "; echo -ne '\033[6n'; while read -n 1 -s -t 1; do out="$out$REPLY"; done
$ echo -n $out | xxd
0000000: 676f 7420 1b5b 3234 3b31 52 got .[24;1R
$
Для control+eтого, что я предполагаютерминал может отправить что-то обратно, но для этого его необходимо настроить:
ENQ Return Terminal Status (Ctrl-E). Default response is an empty
string, but may be overridden by a resource answerbackString.