2016-11-10 478 views
0

我正在学习bash脚本,我想每5秒调用一次函数x秒。当脚本运行时,x由命令行参数确定。我试过手表,但它似乎永远持续下去,我似乎没有能力在x秒后返回。可能有睡眠的方式,但它似乎笨拙,我必须处理当地的漂移。有没有优雅的解决方案?Shell脚本运行命令每5秒x秒数

我的代码:

#!/bin/bash 

if [ $# -ne 1 ]; then # only 1 command line arg allowed 
    echo "Incorrect arguments" 
    exit 1 
elif ! [[ $1 =~ ^[0-9]+$ ]]; then # arg must be digit 
    echo "Argument must be a positive number" 
    exit 1 
fi 

ask() 
{ 
    OUTPUT=$(snmpwalk -v2c -c community server oib) 
    CLEANOUTPUT="${OUTPUT:32}%" 
    echo $CLEANOUTPUT 
} 

#export -f ask 
#watch -n5 ask 

回答

2

SECONDS变量计算自bash开始的秒数:这个简单的方法sleep 5后的最后运行,即使你知道

#!/bin/bash 

while ((SECONDS <= 20)) 
do 
    echo "Running something" 
    sleep 5 || break 
done 
echo "Done" 

它会超过20秒,并且不会考虑命令的运行时间(如果该命令运行2秒钟,它将最终启动每7秒一次)。

+0

感谢提示SECONDS –

+0

为什么睡眠5 || break'?不睡觉返回0,所以休息永远不会被调用?即使它被调用,它会做什么,在“完成”之前? –

+0

当被杀死/中断或者用时间​​说明符调用当前平台认为无效的时候,例如GNU的'0.5'或'1m',或者由于某种原因时间变量结束为空或者错误时'sleep'返回非零值 –

0
#!/bin/bash 
if [ $# -ne 1 ]; then # only 1 command line arg allowed 
    echo "Incorrect arguments" 
    exit 1 
elif ! [[ $1 =~ ^[0-9]+$ ]]; then # arg must be digit 
    echo "Argument must be a positive number" 
    exit 1 
fi 

iterations=$(($1/5)) 
for i in $(seq 1 $iterations); 
do 
     OUTPUT=$(snmpwalk -v2c -c community server oib) 
     CLEANOUTPUT="${OUTPUT:32}%" 
     echo $CLEANOUTPUT 
     sleep 5 
done  
+0

(我知道是不推荐的睡眠,只是以为我会告诉你我怎么会做) – UltrasoundJelly

+0

对不起,我不希望它运行对于x次,我希望它运行x秒。所以如果我把20放在命令行上,它应该运行20秒,每5秒输出一次,所以我会得到4个输出 –

+0

修正了我的答案。据我所知,经过一定次数的迭代后,无法停止监视。 – UltrasoundJelly

1

如果你想多一点与准确的时机,你可以把一个sleep进入后台,做力所能及的工作是必需的,然后用wait,这将阻止前台处理,直到sleep退出。尽管准确度不够完美,但至少不包括工作部分所花费的时间。

喜欢的东西:

#!/bin/bash 

LOOPTIMES=3 
REPEATEVERY=5 # seconds 

for ((count=0 ; $count < $LOOPTIMES ; count++)) 
do 
    /bin/sleep $REPEATEVERY & 

    echo "Doing work $count..." 
    # do whatever 

    wait # this will wait until the sleep exits 
done 

退出0