Чтение строки ответа терминала в переменную

Чтение строки ответа терминала в переменную

С использованиемБаш, как я могу прочитать ответ терминала в переменную без взаимодействия с пользователем? Следующий однострочный код все еще требует 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 секунды, и позволить ему вернуться без чтения каких-либо символов. Чтобы увидеть, как сохраняются/восстанавливаются настройки, полезно прочитать скрипт.

Дальнейшее чтение:

решение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.

Связанный контент