限制Linux命令每单位时间执行次数的方法

时间:2012-08-16 19:40:11

标签: shell time limit rate

我想限制在给定时间段内执行命令的次数。我知道一种方法可以做到这一点,但我的方式并不整洁,我希望有关更好的方法来实现这一目标的建议。具体来说,我处理的场景如下:

我正在使用Motion程序来监控和记录网络摄像头中的图像。程序保存图像并在检测到运动时执行命令。我希望它执行的命令之一是一个简单的命令,可以在检测到运动时向我发送电子邮件。出现困难是因为此命令最终可能每秒执行多次。这可以很快导致在很短的时间内发送数千封电子邮件。我想我想要的是一个如下的程序:

on motion detected
 Has it been more than 1 minute since motion was last detected?
  If it has, send a notification e-mail.
  If it has not, don't send a notification e-mail.

我想在一个简洁的命令中结束该程序。我目前的方法是保存一个临时文件,我怀疑这不是最好的做事方式。

感谢您对此的任何想法!

2 个答案:

答案 0 :(得分:1)

嗯,这是我每次检测到动作时运行的脚本类型:

#!/bin/bash
    #user variables #userSet
        timeIntervalInSecondsBetweenCommandExecutions=120
        lastExecutionTimeFileName="last_command_execution_time.txt"
        command=$(cat << 2012-08-20T1654
twidge update "@<Twitter account> motion detected $(date "+%Y-%m-%dT%H%M")";
echo "motion detected" | festival --tts
2012-08-20T1654
)
    # Get the current time.
        currentTimeEpoch="$(date +%s)"
    # Check if the last execution time file exists. If it does not exist, run the command. If it does exist, check the time stored in it against the current time.
        if [ -e ${lastExecutionTimeFileName} ]; then
            lastCommandExecutionTimeEpoch="$(cat "${lastExecutionTimeFileName}")"
            timeInSecondsSinceLastCommandExecution="$(echo "${currentTimeEpoch}-${lastCommandExecutionTimeEpoch}" | bc)"
            # If the time since the last execution is greater than the time interval between command executions, execute the command and save the current time to the last execution time file.
                if [ ${timeInSecondsSinceLastCommandExecution} -ge ${timeIntervalInSecondsBetweenCommandExecutions} ]; then
                    eval ${command}
                    echo "${currentTimeEpoch}" > "${lastExecutionTimeFileName}"
                fi
        else
            eval ${command}
        fi

简而言之,它正在使用一个文件记住上次运行的时间。所以,这是一个答案,但我仍然认为它不够优雅。

答案 1 :(得分:0)

传统方法是创建一个文件,使用它在其内容中或通过其元数据(mtime e.t.c。)存储时间戳。没有其他标准方法可以在进程外部获取持久性信息 - 我假设您会考虑数据库等等过度。

但是,如果调用者(例如motion阻止等待您的流程完成,则可能有替代方案。在这种情况下,您的脚本可能如下所示:

#!/bin/sh

echo "The Martians are coming!" | mail -s "Invasion" user@example.com

sleep 60

最后一行确保等待此脚本终止的任何调用者必须等待至少60秒,这会产生最大速率限制。