Краткий ответ:
Добавить параметр -s
для первой команды чтения и параметр -ei
для второй команды чтения:
read -s -N 1 -t 10 -p "What is your name? > " a
[ "$a" != "" ] && read -ei "$a" b && echo "Your name is $b" || echo "(timeout)"
Или с лучшей обработкой пустого ввода:
read -s -N 1 -t 10 -p "What is your name? > " a || echo "(timeout)" \
&& [ -n "$a" ] && read -ei "$a" b || echo \
&& echo "Your name is \"$b\""
Уточненный ответ:
С помощью ответа @ chepner (спасибо за опцию -ei
!) И комментария @ paul-hodges, которая привела меня к статье, пропагандирующей опцию -s
read, я смог создать рабочий раствор очень похож на мой оригинальный 2-х линейный:
read -N 1 -t 10 -s -p "What is your name? > " a
[ "$a" != "" ] && read -ei "$a" b && echo "Your name is $b" || echo "(timeout)"
Некоторым из вас может понравиться более сложная версия той же функциональности:
if read -N 1 -t 10 -s -p "What is your name? " FIRST_CHARACTER; then
read -ei "$FIRST_CHARACTER" FULL_NAME
echo "Your name is $FULL_NAME"
else
echo "(timeout)"
fi
Пояснение:
- Опция
-s
в первой команде чтения гарантирует, что FIRST_CHARACTER не будет распечатан во время ввода.
- опция
-N 1
или -n1
обеспечит чтение только первого символа в переменной FIRST_CHARACTER
- опция
-ei
будет читать $FIRST_CHARACTER
в FULL_NAME, прежде чем пользователь продолжит писать символы от 2 до n.
- пользователь может пересмотреть свой ответ, и он может удалить весь ввод, включая первый символ с пробелом.
У меня есть тест, и комбинация этих опций, кажется, помогает.
Устранение предостережения с пустым вводом
Однако есть небольшое предупреждение: если пользователь просто набирает <enter>
: вторая команда чтения будет ждать ввода, пока пользователь не нажмет <enter>
второй раз. Это можно исправить следующим образом:
if read -N 1 -t 10 -s -p "What is your name? " FIRST_CHARACTER; then
if [ -n "$FIRST_CHARACTER" ]; then
read -ei "$FIRST_CHARACTER" FULL_NAME
else
echo
fi
echo "Your name is \"$FULL_NAME\""
else
echo "(timeout)"
fi
В стиле с двумя линиями это даст нам три линии следующим образом:
read -N 1 -t 10 -s -p "What is your name? > " a || echo "(timeout)" \
&& [ -n "$a" ] && read -ei "$a" b || echo \
&& echo "Your name is \"$b\""
* * Тест тысяча сорок-девять
Код обеих версий (вложенная версия if и трехстрочный) будет вести себя следующим образом:
- Если пользователь ничего не делает в течение 10 секунд, вывод выдаст
What is your name? (timeout)
- Если пользователь пишет
Oliver<enter>
, вывод будет
What is your name? Oliver
Your name is "Oliver"
- если пользователь начинает писать «Оливер», а затем считает, что хочет, чтобы его звали «Майкл», он может полностью удалить «Оливер» с помощью клавиши возврата и заменить его соответствующим образом. Выход будет:
What is your name? Oliver
после ввода имени "Оливер". Затем, после нажатия клавиши Backspace 6 или более раз:
What is your name?
и после ввода Michael<enter>
:
What is your name? Michael
Your name is "Michael"
Надеюсь, это поможет.