bash读取超时仅适用于用户输入的第一个字符
我搜索了一个简单的解决方案,该解决方案将读取具有以下功能的用户输入:bash读取超时仅适用于用户输入的第一个字符,bash,timeout,user-input,Bash,Timeout,User Input,我搜索了一个简单的解决方案,该解决方案将读取具有以下功能的用户输入: 如果根本没有用户输入,则10秒后超时 如果在前10秒内键入第一个字符,则用户有无限的时间完成其答案 我已经找到了一个类似的解决方案(在每个输入字符后超时)。尽管如此,这并不是我一直在寻找的功能,因此我开发了一个双线解决方案,如下所示: read -N 1 -t 10 -p "What is your name? > " a [ "$a" != "" ] && read b && ech
- 如果根本没有用户输入,则10秒后超时
- 如果在前10秒内键入第一个字符,则用户有无限的时间完成其答案
read -N 1 -t 10 -p "What is your name? > " a
[ "$a" != "" ] && read b && echo "Your name is $a$b" || echo "(timeout)"
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\""
如果用户在输入第一个字符前等待10秒,输出将为:
What is your name? > (timeout)
如果用户在10秒内键入第一个字符,则他有无限时间完成此任务。输出如下所示:
What is your name? > Oliver
Your name is Oliver
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
但是,有以下警告:第一个字符在键入后不可编辑,而所有其他字符都可以编辑(退格和重新键入)
您对解决警告有什么想法吗?或者您对请求的行为有其他简单的解决方案吗?启用
readline
并添加$a
作为第二次读取的默认值
# read one letter, but don't show it
read -s -N 1 -t 10 -p "What is your name? > " a
if [ -n "$a" ]; then
# Now supply the first letter and let the user type
# the rest at their leisure.
read -ei "$a" b && echo "Your name is $b"
else
echo "(timeout)"
fi
这仍然会在第一个字母被回答后显示第二个提示,但我认为没有更好的方法来处理这个问题;无法“取消”读取的超时。理想的解决方案是使用一些命令而不是读取
,但是您必须自己编写(可能是作为可加载的内置程序,在C中)。此解决方案可以
read -n1 -t 10 -p "Enter Name : " name && echo -en "\r" &&
read -e -i "$name" -p "Enter Name : " name || echo "(timeout)"
注意:第二个读取
使用从第一个(-i
选项)捕获的文本提供可编辑的缓冲区。回车和相同的提示给用户一种印象,即他正在输入相同的值。测试条件:
GNUBash,版本4.4.19(1)-发布
Ubuntu 18.04.2 LTS
我创建了一个函数来解决第一个字母不可编辑的警告,如下所示。我只在本地linux服务器上进行了测试,我不认为这会在其他地方或新/旧版本的BASH上起作用(或者阅读了相关内容,但我无法说出我正在运行的版本)
您可以调用此函数,如下所示:
declare n=""
__readInput
if [[ $? -eq 0 ]] || [[ ${#n} -eq 0 ]] ;then
echo "Your name is $n"
else
echo "I'm sorry, I didn't quite catch your name!"
fi
上述说明的注意事项
所以,你有一个我修正的警告,也许你(或我们的朋友)可以修正这个。任何未包含在$rg
REGEX变量中的输入字符都将被视为退格。这意味着您的用户可以点击F7
,=
,\
,或者除$rg
中指定的字符以外的任何字符,并且将被视为退格简短回答:
在第一个读取命令上添加-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行程序非常相似的工作解决方案:
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
选项将确保键入时不会打印出第一个字符
-n1
或-n1
选项将确保仅将第一个字符读入第一个字符变量
-ei
选项将把$FIRST\u CHARACTER
读入全名,然后用户继续将字符2写入n
- 用户可以重新考虑他的答案,并且可以删除整个输入,包括带有退格的第一个字符
我已经对它进行了测试,这些选项的组合似乎达到了目的
解决带有空输入的警告
但是,还有一个小警告:如果用户只是键入
:第二个读取命令将等待输入,直到用户再次按下
。这可以通过如下方式进行修复:
What is your name? > Oliver
Your name is Oliver
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 -p "What is your name? > " a
[ "$a" != "" ] && read b && echo "Your name is $a$b" || echo "(timeout)"
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版本和三行程序)的代码的行为如下:
read -N 1 -t 10 -p "What is your name? > " a
[ "$a" != "" ] && read b && echo "Your name is $a$b" || echo "(timeout)"
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\""
- 如果用户在10秒内没有做任何事情,输出将产生
- 如果用户写入
Oliver
,则输出将为
- 如果用户开始写“Oliver”,然后认为他想被称为“Michael”,他可以使用退格键完全删除“Oliver”,并相应地替换它。输出将是:
在输入名字“奥利弗”后。然后,按backspace键6次或以上后:
What is your name?
在输入Michael之后:
希望这能有所帮助。我很确定所有这些问题都可以解决,但处理每一个问题,尤其是所有问题的代码并不重要。您可能会在中找到一些有用的提示。可以通过在第一个读取命令上添加-s
选项和在第二个读取命令上添加-ei
选项来解决问题。更多信息见下文的答案,更详细的答案见下文。感谢您的链接,它将我们引导到-s
选项。因此,我已将您的评论标记为有用。我测试了您的解决方案,出现了一个奇怪的效果:第一个字符加倍。警告仍然存在,即第一个加倍字符无法删除。例如,我键入“Oliver”,然后我将看到“OOliver”。我使用了10次backspace,但是第一个O不能被删除。如果我接着键入“Michael”,我会得到“OMichael”。答案对我仍然很有帮助,因为我已经了解了有用的-ei
阅读选项。因此,我会按相应的三角形。哦,对不起<代码>