【问题标题】:Linux Read - Timeout after x seconds *idle*Linux 读取 - x 秒后超时 *空闲*
【发布时间】:2017-07-23 23:45:17
【问题描述】:

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

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

所以,脚本遵循这个概念

#!/bin/bash
function refreshscreen(){
  # This function refreshes a "statistics screen"
  ...
  echo "Enter command to override update"
  read -t 10 variable
}

此脚本刷新统计屏幕,并允许用户暂停更新以代替内置于 case 语句中的命令。但是,无论用户是否正在输入,读取都会在 10 秒后超时 (read -t 10)。

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

我曾考虑在读取命令暂停屏幕以检查不活动之前在循环结束时运行后台脚本,但尚未找到使该命令工作的方法。

【问题讨论】:

    标签: linux bash timeout


    【解决方案1】:

    您可以在循环中使用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 上中断,您可以多次调用此函数,直到获得您期望的所有输入。

    【讨论】:

    • 一个非常彻底的结论。 +1 考虑每个字母而不是每个命令。谢谢!
    【解决方案2】:

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

    • 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
    
    

    警告:第一个字符一旦输入就不可编辑,而所有其他字符都可以编辑(退格和重新输入)。有什么简单的解决方案的想法吗?

    【讨论】:

    • 在 SO 上创建这个作为它自己的问题,并将其链接粘贴到下面,我愿意提供一个可能的解决方案
    • @timtj:非常感谢您的提议。我已经提出了问题here
    猜你喜欢
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多