2016-07-14 110 views
1

我想监视一个无限运行的命令的输出,并且每隔一段时间打印一行。它显示硬件按钮的事件,每行显示一个按钮。如何检测连续按下按钮的频率?

我的脚本在接收行时应该运行其他命令,但问题是这些行的内容不能决定必须运行哪个命令,而是给定延迟内的行数。

换句话说,用户可以多次推动这个被监视的按钮,并且根据按钮被按下的频率执行不同的命令。用户在两次按压之间有2秒的时间,然后根据连续按下的次数选择命令。

我目前没有与这个结构的bash脚本:

#!/bin/bash 
lasttouch="0" 

MONITORING_COMMAND 
| while read line; do  
    if [ $(date +%s --date="2 seconds ago") -lt $lasttouch ]  
    then 
     COMMAND2 
    else 
     lasttouch=$(date +%s) 
     COMMAND1 
    fi  
done 

然而,这最多只能处理两个连续压机,它的每一个事件执行COMMAND1,即使随后的新闻在时间和COMMAND2如下宜反而运行。

我实际上不知道如何在Bash中正确实现它。我想我需要某种多线程,一个线程监听传入的行并增加一个计数器,另一个线程在每个事件之后运行2秒倒计时,并在计数超时而没有其他事件时重置计数器并执行相应的命令。

回答

1

在执行COMMAND1之前,您可以设置一个等待所需时间的单次推送功能,记录它的pid为$!,并在实际收到所需时间之前的双推时终止该功能。

这里是700毫秒的延迟的一个示例:

#!/bin/bash 

MONITORING_COMMAND="your monitoring command here" 
PUSH_NUM=1   #1 => until double push detection | 2 => until triple push detection etc... 
MAX_DELAY=700  #the delay in between push in milliseconds 

inc=0 
remaining_delay=0 

# wait_push <command value> <time left to sleep before taking the push> 
wait_push() 
{ 
    if [ ! -z "$2" ]; then 
     sleep $2 
    fi 
    inc=0 
    #switch between all your command here 
    #COMMAND0 : normal push 
    #COMMAND1 : double push 
    #COMMAND2 : triple push etc.. 
    echo "push is detected here: execute $1 here" 
    pid="" 
    lasttouch="" 
} 

$MONITORING_COMMAND | while read line ; do 

    current=$(($(date +%s%N)/1000000)) 

    if [ ! -z "$lasttouch" ]; then 

     diff=`expr $current - $lasttouch` 

     if test $diff -lt $MAX_DELAY 
     then 

      inc=$((inc+1)) 

      if [ "$inc" -lt $PUSH_NUM ]; then 

       if [ ! -z "$pid" ]; then 
        kill $pid 2>/dev/null 
        wait $pid 2>/dev/null 
       fi 
       remaining_delay=$((remaining_delay-diff)) 
       time=`awk -v delay=$remaining_delay 'BEGIN { print (delay/1000) }'` 
       #normal push 
       wait_push "COMMAND${inc}" $time & 
       pid=$! 
       continue 

      elif [ "$inc" == $PUSH_NUM ]; then 

       if [ ! -z "$pid" ]; then 
        kill $pid 2>/dev/null 
        wait $pid 2>/dev/null 
       fi 
       wait_push "COMMAND${inc}" 
       continue 

      fi 
     else 
      inc=0 
     fi 
    fi 

    if [ "$inc" == 0 ]; then 
     remaining_delay=$MAX_DELAY 
     time=`awk -v delay=$MAX_DELAY 'BEGIN { print (delay/1000) }'` 
     #normal push 
     wait_push "COMMAND${inc}" $time & 
     pid=$! 
    fi 

    lasttouch=$current 
done 

可以提高推号码编辑可变PUSH_NUM

  • 双推:PUSH_NUM=1
  • 特里普尔推:PUSH_NUM=2
  • etc

您将拥有wait_push函数中的所有命令处理。这考虑了所有连续推送事件之间的剩余时间(其不超过MAX_DELAYms)

+0

有趣的方法。我不知道如何修改它,而不仅仅是2次? –

+0

我用动态数字推动 –

+0

更新了答案,我很抱歉,但是有一个误解。我不希望command1在推动次数较多时运行,command2运行次数较多,但我有很多命令(例如5个),每个按钮次数与不同的命令相对应。 –