如何使用 Bash 读取超时?

Posted

技术标签:

【中文标题】如何使用 Bash 读取超时?【英文标题】:How to use Bash read with a timeout? 【发布时间】:2021-11-29 23:51:27 【问题描述】:

我可以使用read 要求用户按Enter,并通过调用sleep 让他等待。但我想不出同时做这两件事的方法。我希望用户可以选择:

Ctrl+C 取消,Enter 继续或等待 10 秒

我该怎么做?

【问题讨论】:

【参考方案1】:

bash 中,read 有一个-t 选项,您可以在其中指定超时。从手册页:

read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...]

-t timeout: 如果在 timeout 秒内没有读取完整的输入行,则会导致读取超时并返回失败。如果 read 不是从终端或管道读取输入,则此选项无效。

下面的成绩单(不按回车键):

$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; echo ; date
Tue Feb 28 22:29:15 WAST 2012
Hit ENTER or wait ten seconds
Tue Feb 28 22:29:25 WAST 2012

另一个,几秒钟后按回车键:

$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; date
Tue Feb 28 22:30:17 WAST 2012
Hit ENTER or wait ten seconds
Tue Feb 28 22:30:19 WAST 2012

还有一个,按 CTRL-C:

$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; echo ; date
Tue Feb 28 22:30:29 WAST 2012
Hit ENTER or wait ten seconds

【讨论】:

我非常喜欢这样详细的答案。向你致敬! ubuntu。 -t - 非法选项 @ses,确保您使用的是内置的 bash,而不是某些外部工具。 如果您正在编写一个 shell 脚本,请确保它以 #!/bin/bash 而不是 #!/bin/sh 开头。后者可能会或可能不会工作,具体取决于 /bin/sh 实际上是哪个二进制文件。你被允许写#!/bin/sh如果并且只有你的脚本是POSIX兼容的,它很肯定不是。 使用这个时,确保你的脚本是#!/bin/bash,而不是#!/bin/sh,因为-t选项不兼容POSIX(iaw脚本可能无法在每台机器上运行)【参考方案2】:

read 内置有超时。

read -t 10

会做的

【讨论】:

【参考方案3】:

基于上述深思熟虑的答案,读取的返回值有助于区分用户的空响应(例如默认操作的“按 Enter”)和超时。

read -t 5 -p "Prompt " RESP
if [[ $? -gt 128 ]] ; then
    echo -e "\nTimeout"
else
    echo "Response = \"$RESP\""  # adding quotes so empty strings are obvious
fi

另一个有用的消息是-p "prompt " 被写入标准错误(不是标准输出),所以如果你重定向标准错误,提示将不会显示。这方面的一个示例是将执行跟踪记录到日志文件以供以后分析。要在这种情况下使用 read -p Prompt,您可以将 stderr 重定向到用户,仅用于读取语句。

set -x
exec 2>logfile
read -t 5 -p "Prompt " RESP 2>/dev/tty

【讨论】:

【参考方案4】:

来自bash reference manual:

read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt][-t timeout][-u fd] [name ...]

【讨论】:

以上是关于如何使用 Bash 读取超时?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 读取大型 Firestore 集合而不会遇到 503 超时错误

C++ Boost ASIO:如何读取/写入超时?

bash只读取用户输入的第一个字符的超时

如何使用 Bash 从 JAR 中读取 MANIFEST.MF 文件

Google Pub/Sub 如何在 Pull 上设置读取超时

如何使用 Bash 编写的 IRC 机器人从 IRC 频道读取消息?