简答:
在第一个读取命令上添加一个-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 阅读选项的文章,我能够创建一个工作解决方案与我原来的 2-liner 非常相似:
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 选项将在用户继续将字符 2 写入 n 之前将 $FIRST_CHARACTER 读入 FULL_NAME。
- 用户可以重新考虑他的答案,他可以删除整个输入,包括带有退格的第一个字符。
我已经测试过了,这些选项的组合似乎可以解决问题。
使用空输入解决警告
但是,仍然有一个小警告:如果用户只键入 <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 版本和三行代码)的行为如下:
What is your name? (timeout)
- 如果用户写
Oliver<enter>,输出将是
What is your name? Oliver
Your name is "Oliver"
- 如果用户开始写“Oliver”,然后考虑,他想被称为“Michael”,他可以用退格键完全删除“Oliver”并相应地替换它。输出将是:
What is your name? Oliver
在输入名字“奥利弗”之后。然后,按退格键 6 次或更多次后:
What is your name?
然后输入Michael<enter>:
What is your name? Michael
Your name is "Michael"
希望对您有所帮助。