【问题标题】:Shell Script: How do I read input with a timeout, but not continue when enter is pressed?Shell 脚本:如何读取超时输入,但按下输入时不继续?
【发布时间】:2014-03-23 19:55:32
【问题描述】:

我是论坛的新手,如果这篇文章不正确,我很抱歉。

我的代码如下:

#!/bin/bash

number=0

while (true); do
echo "Your number is: $number"
echo ""
echo "Press space to add one to your number."
echo ""
read -t 1 -n 1 input

if [ "$input" == " " ]; then
    number=$((number+1))
fi
done

我想让这个人不能只是按住空格键来增加数字。有没有办法让这个人只有在超时完成后才能按空格键?

换句话说,如果你在 0.25 秒时输入一个键,你不会直接跳到下一步,程序还要等待 0.75 秒才能继续,因此总共需要 1 秒。

就像在没有-n 1 的普通read 命令中按回车键提交输入一样,即使超时未完成,它也会继续。另一种方法是在读取用户输入时休眠,并在休眠完成后终止它。

我也试过这个:

read -n 1 input & sleep 1 & wait

然后弹出这个:

[15] 94977
[16] 94978

[15]+  Stopped                 read -n 1 input
[16]   Done                    sleep 1

当它应该同时运行它们时,为什么它会停止进程?以下代码同时运行所有三个:

sleep 1 & sleep 2 & sleep 3 & wait

总共休眠 3 秒,而不是 6 秒。

我希望你明白我在说什么。

【问题讨论】:

  • 仅供参考,while (true) 的效率远低于while true,因为它会生成一个子shell 并在其中调用true

标签: macos bash shell input terminal


【解决方案1】:

不要放“& sleep” 将睡眠换行

read -n 1 -t 1 input sleep 1

【讨论】:

  • 这不是问题。我想做的是让你只能在一秒钟的时间范围内按空格,这样就有一个标准的睡眠时间,而不是一个变化的。
【解决方案2】:

试试这个!

更改:read -n 1 input & sleep 1 & wait

这个:read -n 1 input && sleep 1

原因是 & 将在后台运行程序/命令。 && 将在最后一个程序/命令完成后运行,并且仅当它以错误状态 1(成功执行)退出时运行,或者您也可以使用 ;这将告诉它在最后一个程序/命令之后运行并关心退出状态。如果可能的话,我还建议使用 usleep 而不是 sleep 如果它安装了相同的语法,但它会是微秒而不是秒。 usleep 1000 = sleep 1

【讨论】:

    【解决方案3】:

    你怎么看?

    你可以试试(作为我的朋友@jaypal 指导):

    #!/bin/bash
    
    number=0
    while (true); do
        echo "Your number is: $number"
        IFS= read -t 5 -n 1 -p "Press space to add one to your number: " input
        # Check for Space
        if [[ $input =~ \ + ]]; then
           echo "space found"
           let number=number+1
           echo "$number"
        # Check if input is NULL
        elif [[ -z "$input" ]]; then
           echo "input is NULL"
        fi
    done
    

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

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

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

    下面的成绩单(不按ENTER):

    $ 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
    

    另一个,几秒钟后按 ENTER

    $ 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
    

    【讨论】:

      猜你喜欢
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      相关资源
      最近更新 更多