问题描述:这几天室友遇到一个麻烦,他写的一个shell脚本在事件触发时总是被执行多次而出错,他想要控制脚本的执行次数,即每次触发仅执行一次就行了。懒得去研究为什么被多次触发,希望仅仅在脚本内部写几行代码便解决这个问题。下面我向大家介绍一下我想的一种解决办法。
解决办法:
1. 创立一个共享文件,向里面写入当前时间戳;
2. 脚本读取共享文件内的时间戳,与当前时间作差;
3. 如果差值小于5秒,则直接退出(exit),如果差值大于5秒,则更新共享文件内的时间戳,并执行后续程序。
因为对于他这种情况,多次执行是因为事件触发在极短的时间内多次发生,所以在5秒内仅执行一次是满足要求的。
下面我贴出shell脚本
#!/bin/sh
file_name = "/mnt/flag"
if [ ! -f "$file_name" ]; then
touch $file_name
last_time=$(date -u +%s)
echo $last_time > $file_name
else
for i in `cat $file_name`
do
now_time=$(date -u +%s)
if [ `expr $((now_time)) - $((i))` -lt 5 ]; then
echo "please wait..."
exit
else
echo "update the time"
echo $now_time > $file_name
echo $now_time
fi
done
fi
这样,你再在这段代码后加入你的程序,它在5s内就不会被重复执行了。
讨论
也许你会觉得通过共享文件来通信太麻烦,不如用环境变量来得方便,你想的办法可能会是下面这个样子
#!/bin/bash
if [ ! $LAST_TIME ]; then
export LAST_TIME=$(date -u +%s)
source test.sh [ $LAST_TIME ]
else
now_time=$(date -u +%s)
if [ `expr $((now_time)) - $(($LAST_TIME))` -lt 5 ]; then
echo "please wait..."
exit
else
echo "update the time"
export LAST_TIME=$now_time
source test.sh [ $LAST_TIME ]
echo $now_time
fi
fi
source后面的test.sh指的是本文件的文件名。像这样通过添加环境变量的方式,想要得到一个类似于全局变量的效果,是不能成功的。这是因为在每个shell启动的时候,都会继承其父shell的环境变量到本地,脚本对环境变量的修改,其生命周期随此shell执行结束而结束,对其父shell并不能产生影响。
综上所述,要想在shell脚本中实现全局变量的效果,一条可行的方案是使用共享文件。