Linux读取-x秒后超时*空闲*

Linux读取-x秒后超时*空闲*,linux,bash,timeout,Linux,Bash,Timeout,我在继承了管理方面的服务器上有一个(bash)脚本,最近发现了脚本中的一个漏洞,没有人引起我的注意 在发现这个问题后,其他人告诉我,这让他们很恼火,但从来没有告诉我(太好了…) 因此,脚本遵循这个概念 #!/bin/bash function refreshscreen(){ # This function refreshes a "statistics screen" ... echo "Enter command to override update" read -t 10

我在继承了管理方面的服务器上有一个(bash)脚本,最近发现了脚本中的一个漏洞,没有人引起我的注意

在发现这个问题后,其他人告诉我,这让他们很恼火,但从来没有告诉我(太好了…)

因此,脚本遵循这个概念

#!/bin/bash
function refreshscreen(){
  # This function refreshes a "statistics screen"
  ...
  echo "Enter command to override update"
  read -t 10 variable
}
此脚本刷新统计屏幕,并允许用户暂停更新,以代替
case
语句中内置的命令。但是,无论用户是否在键入,读取时间都会在10秒后超时(
read-t10

长话短说,如果用户正在主动键入命令,是否有方法防止读取超时?最好的情况是“空闲/非活动秒超时”,而不是x秒后超时


我曾考虑在读取命令暂停屏幕以检查是否处于非活动状态之前,在循环结束时运行一个后台脚本,但没有找到使该命令工作的方法。

您可以在循环中使用
read
,一次读取一个字符,然后将其添加到最终读取字符串中。这将为用户提供每个字符(而不是每个命令)的超时时间。下面是一个示例函数,您可以将其合并到脚本中,它显示了我所说的内容:

read_with_idle_timeout() {
    local input=""

    read -t 10 -N 1 variable

    while [ ! -z $variable ]
    do
        input+=$variable
        read -t 10 -N 1 variable
    done

    echo "Read: $input"
}
这将给用户10秒的时间来键入每个字符。如果他们停止键入,您将获得与超时发生之前开始键入的命令一样多的命令,然后您的
case
语句可以处理它。也许您可以将最后一个字符串存储在全局变量中,或者直接将此代码放入其他函数中


如果您需要多个单词,因为
read
$IFS
上中断,您可以多次调用此函数,直到您获得所需的所有输入。

我已搜索了一个简单的解决方案,可以执行以下操作:

  • 如果根本没有用户输入,则10秒后超时
  • 如果在前10秒内键入第一个字符,则用户有无限的时间完成其答案
这可以通过以下两行实现:

read -N 1 -t 10 -p "What is your name? > " a
[ "$a" != "" ] && read b && echo "Your name is $a$b" || echo "(timeout)"
如果用户在输入第一个字符前等待10秒,输出将为:

What is your name? > (timeout)
如果用户在10秒内键入第一个字符,则他有无限时间完成此任务。输出如下所示:

What is your name? > Oliver
Your name is Oliver


注意事项:第一个字符在键入后不可编辑,而所有其他字符都可以编辑(退格和重新键入)。有什么简单的解决办法吗?

一个非常彻底的结论+1用于考虑每个字母而不是每个命令。谢谢创建这个,因为这是自己的问题,所以在这里,并粘贴在下面的链接其链接,我愿意提供一个可能的解决方案solution@timtj:非常感谢你的提议。我已经提出了这个问题。