Bash 读取并在输入后等待

Bash read and wait even after input

在 bash 中,我想读取用户的键输入,甚至在按下键后还要等待。 我用

read -n 1 -s -t 0.05 key

但输入后它停止等待。无论如何,我都想等待 0.05 并将按下的第一个键存储在变量键中。

正如评论中指出的那样,使用sleep。在 sleep 期间输入的所有内容都将打印在终端上(对于不使用标准输入的每个命令)。使用 stty 隐藏此输出。

  • stty -echo 禁用输出。
  • stty echo 启用输出(将打印到目前为止隐藏的未使用字符)。

您可能只想等待剩余时间,而不是额外的 0.05 秒。有两种方法:

简单但可能不可靠的方法

使用sleep before read — 这样你既不必测量等待时间也不必计算剩余时间:

stty -echo
sleep 0.049
read -n1 -s -t0.001 key;
stty echo;

echo "key was $key"

超时read -t… 必须足够长才能实际读取缓冲的字符。您可以通过将很长的一行复制粘贴到您的终端来测试这一点——read 只会读取其中的一部分。在较慢的系统上,您可能必须增加 0.001。但请记住,用户的综合等待时间可能只是睡眠时间,即越大-t意味着精度越低。

复杂但稳健的方式

要避免该问题,您可以将 sleep 放在 read 之后并计算剩余的等待时间,这当然需要更多工作。这是 bash 5.0 或更高版本中的解决方案:

# all variables of the form tSomething are in μs = 10^-6 s
stty -echo
tStart="${EPOCHREALTIME/./}" 
read -n1 -s -t0.05 key;
tEnd="${EPOCHREALTIME/./}"
printf -v tWait %07d "$((tStart + 50000 - tEnd))" # 50000 μs = 0.05 s
sleep "${tWait:: -6}.${tWait: -6}"
stty echo

echo "key was $key"