Я всегда использовал Unetbootin, чтобы сделать эти типы установок. Это - автономный исполняемый файл, таким образом, нет ничего для установки, просто загрузите его и работайте.
Что касается чтения
оболочки, то это - независимо от того, ограничиваете ли вы его общее количество байтов на чтение
или нет - это все равно не даст вам нажатий клавиши на чтения
. Будет только фиксированное количество символов на чтение
. Чтобы получить нажатие клавиши на чтение
, вам необходимо заблокировать ввод - и лучший способ сделать это, вероятно, - dd
.Это функция оболочки, которую я написал пару месяцев назад, когда экспериментировал с блокировкой dd
на терминальном вводе / выводе:
printkeys()( IFS= n=1
set -f -- "$(tty <&2)"
exec <${1##[!/]*};set \\t
_dd()( c=conv=sync,unblock i=ibs=72 b=bs=8
dd bs=7 ${c%,*} | dd $i o$b c$b $c
) 2>/dev/null
trap " trap '' TTOU TTIN
stty '$(stty -g
stty raw isig inlcr)' " INT EXIT
_dd |while ${2:+:} read -r c || exit 2
do case $#:$c in (1:): ;;
(*:?*) set ":%d$@" \
\'${c%"${c#?}"} ;
c=${c#?} ;;
(*) printf "$@" ;
[ 0 -eq $((n=n<4?n+1:0)) ] &&
set '\n\r'||set \\t ;; esac
done
)
Видите ли, в приведенном выше случае ввод терминала фильтруется по двум dd
обрабатывает конвейер. Терминал устанавливается с stty
в режим raw в ловушке
, которая также восстанавливает конечное состояние при прерывании INT
или EXIT
на то, что было, когда функция была вызвана (что, вероятно, можно сделать с помощью CTRL + C или любой другой клавиши прерывания) . В режиме raw терминал сбрасывает ввод любому считывающему устройству, как только он поступает - нажатие клавиши за нажатием клавиши. Он не просто отправляет байт за раз; он выталкивает весь буфер, как только это возможно. И поэтому, когда вы, например, нажимаете стрелку ВВЕРХ, и ваша клавиатура отправляет escape-последовательность, например:
^[[A
... это три байта, и она нажимает все сразу.
dd
спроектирован так, чтобы удовлетворить любое чтение, как только оно будет предложено - независимо от того, насколько высоко вы установите его ibs =
. Это означает, что, хотя я установил его с помощью ibs = 7
, когда терминал отправляет только три байта, чтение все равно завершается. С этим трудно справиться с большинством других утилит, но dd
conv = sync
заполняет разницу w / \ 0NUL
байтов. Поэтому, когда вы нажимаете стрелку ВВЕРХ на клавиатуре, dd
считывает три байта и записывает 7 в следующий dd
- три байта в escape-последовательности и еще 4 \ 0NUL
с.
Но для того, чтобы получить эти данные при чтении оболочки, вы должны снова заблокировать их, поэтому следующий dd
синхронизирует свой входной буфер до 72 байтов - но он также conv = разблокировать
s это. С преобразованием разблокировать
, dd
разбивает свой ввод на \ n
разделителей ewline для своего счетчика cbs =
, который здесь равен 8. С синхронизация
и разблокировка
(или блок
) преобразования, dd
не синхронизируется на \ 0NUL
s, а скорее на конечных пробелах. Таким образом, для каждых 7 байтов первый dd
записывает в канал между ними, второй dd
буферизует 72 байта - первые несколько соответствуют нажатию клавиш, затем \ 0NUL
с, затем 65 пробелов в конце каждого чтения.
Другая вещь, которую выполняет unblock
, - это убирает конечные пробелы - он съедает столько пробелов, сколько может появиться в конце каждого из его блоков преобразования cbs =
. Таким образом, поскольку dd
записывает вывод с obs = 8
байт на запись, он записывает 9 строк за одно чтение в 2 общих операциях записи в выходной канал. Первая запись - это первая строка, состоящая из 7 байтов, считанных из входного канала, и завершающего символа новой строки - еще одного байта. Следующая запись - 8 новых строк - все сразу и подряд - еще 8 байтов - потому что dd
съедает все 8 пробелов для каждого из этих 8 блоков преобразования.
С другой стороны этих двух dd
s оболочка , в то время как
цикл считывает
s построчно.Он может игнорировать пустые строки - потому что терминал все равно преобразует все символы новой строки в возврат каретки при выводе в соответствии с параметром inlcr
stty
. Но когда он обнаруживает даже один байт в $ c
после того, как ввод оболочки считывает
в его значение, тогда у вас есть нажатие клавиши - и целикомпока ваша клавиатура не отправляет более 7 байтов на нажатие клавиши (хотя для этого просто потребуется другой коэффициент блокировки) .
Когда оболочка нажимает клавишу в $ c
, она выполняет итерацию по байту за байтом и разбивает его на массив, разделенный на '
символов, затем printf
s десятичные значения для каждого байта в $ c
сразу. Если вы запустите эту функцию, вы должны получить следующий результат:
a:97 b:98 c:99 d:100 e:101
f:102 ;:59 ^M:13 ^M:13 ^M:13
s:115 a:97 d:100 f:102 :32
':39 ':39 ':39 a:97 s:115
d:100 f:102 ;:59 ':39 ^[[A:27:91:65
^[[D:27:91:68 ^[[B:27:91:66 ^[[C:27:91:67 ^[[D:27:91:68 ^[[C:27:91:67
^[[A:27:91:65 ^[[D:27:91:68 ^[[C:27:91:67 ^[[B:27:91:66 ^[[D:27:91:68
^[[C:27:91:67 ^[[A:27:91:65 ^[[D:27:91:68 ^[[C:27:91:67 ^[[B:27:91:66
Потому что \ 0NUL
, которые dd
вставляет, чтобы заблокировать нажатия клавиш, испаряются, как только оболочка заполняет значение переменной с ее вводом - вы не можете поместить \ 0NUL
s в переменную оболочки (в любой оболочке, кроме zsh
- в этом случае ее можно настроить таким образом) . Насколько мне известно, это должно работать в любой оболочке - и это определенно работает в bash
, dash
и ksh93
. Он может даже надежно обрабатывать многобайтовый ввод, но я не буду на это ругаться.
В демонстрационном выводе выше фактическому выводу функции для каждой записи предшествует другая информация, которую она не записывает. Каждый отображаемый символ, предшествующий каждому первому появлению :
в любой из вышеперечисленных последовательностей, на самом деле является эхо
терминала, которое можно настроить с помощью stty echo
или - эхо
. Остальное - это то, что печатается как вывод функции - и оно печатается, как вы можете видеть, сразу после ввода.
С bash
вы можете использовать параметр -n
для встроенного чтения
, чтобы ограничить количество читаемых символов без необходимости новой строки:
#!/bin/bash
echo "Ready? [Y/n]: "
read -n 1 y_or_n
echo
case "$y_or_n" in
[Yy]|"")
echo "you said yes"
;;
*)
echo "you said no"
;;
esac
Это работает независимо от того, вызывается ли bash
как sh
или bash
.
См. справку по чтению
или справочную страницу bash
для получения дополнительных сведений.
Обратите внимание, что другие оболочки могут не поддерживать параметр -n
для чтения
. тире
, например, нет.