阅读前清除标准输入

rab*_*bin 15 linux bash shell stdin

我有以下 bash 脚本:

# do some time consuming task here
read -p "Give me some input: " input
Run Code Online (Sandbox Code Playgroud)

现在您可能已经猜到了,如果用户在“耗时任务”期间按了一些随机键,那么不需要的输入也会被考虑在内。stdin在发出读取命令之前如何清除(或至少忽略它)?

小智 23

在 Bash 4 中,您可以将-t(timeout)设置为0. 在这种情况下,read立即返回一个退出状态,指示是否有数据等待:

# do some time consuming task here
while read -r -t 0; do read -r; done
read -p "Give me some input: " input
Run Code Online (Sandbox Code Playgroud)


小智 12

我认为没有办法清除标准输入,但是(使用 bash)您可以在要求输入之前阅读并丢弃那里的内容

#do some time consuming task here
read -t 1 -n 10000 discard 
read -p "Give me some input: " input
Run Code Online (Sandbox Code Playgroud)

这会读取标准输入并超时 1 秒,但如果标准输入中的字符超过 10000,它就会失败。我不知道您可以将 nchars 参数设置为多大。


小智 6

read -d '' -t 0.1 -n 10000
Run Code Online (Sandbox Code Playgroud)

这会读取多行输入,如果用户无意中多次按下输入


小智 6

function clear_stdin()
(
    old_tty_settings=`stty -g`
    stty -icanon min 0 time 0

    while read none; do :; done 

    stty "$old_tty_settings"
)

clear_stdin
Run Code Online (Sandbox Code Playgroud)

  • @kaan_a 当引用时,该命令可能不起作用。这完全取决于“stty”的实现。[规范](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/stty.html#tag_20_123) 指出该工具应该将其自己的输出(即 `stty -g` 的输出)理解为参数** s**(复数!)并且输出不需要引用。如果用引号引起来,则该字符串将是单个参数。规范没有提到“参数”(单数),“stty”不需要以这种形式理解它,它可能会也可能不会理解它。不引用是“必需”的唯一工作方式。 (3认同)
  • 如果省略“function”这个词,它可以通过 `dash` 和任何其他 POSIX 兼容的 shell 来工作。 (2认同)

小智 5

这对我很有效:

function clean_stdin()
{
    while read -e -t 0.1; do : ; done
}
Run Code Online (Sandbox Code Playgroud)