如何在Bash Scripting中包含一个计时器?

时间:2009-08-04 07:27:04

标签: bash timestamp

美好的一天!是否有任何方法可以使用 bash 在脚本中包含计时器(时间戳?或任何术语)?比如说;每60秒,一个特定的功能检查互联网是否关闭,如果是,则它连接到wifi设备,反之亦然。简而言之,该程序不时检查互联网连接。

任何建议/答案将不胜感激。 =)

6 个答案:

答案 0 :(得分:18)

钝版

while sleep 60; do
  if ! check_internet; then
    if is_wifi; then
       set_wired
    else
       set_wifi
    fi
  fi
done

使用sleep本身作为循环条件允许你通过杀死睡眠来打破循环(即如果它是前台进程,ctrl-c会这样做。)

如果我们谈论几分钟或几小时的间隔,cron可能会做得更好,正如Montecristo指出的那样。

答案 1 :(得分:5)

您可能想要 man cron

或者,如果你只需要坚持使用bash,只需将函数调用放在循环内,并在迭代内 sleep 60

答案 2 :(得分:4)

请在此处找到您可以使用的脚本,首先在您的cron作业中添加一个条目,如下所示:

$ sudo crontab -e * * * * * / path / to / your / switcher

这是一种简单的方法,它每分钟都会持续ping一个活动服务器,如果服务器无法访问,它将切换到下面定义的第二个路由器。

肯定有更好的方法来利用这个问题。

$ cat>切换器

#!/bin/sh

route=`which route`
ip=`which ip`

# define your email here
mail="user@domain.tld"

# We define our pingable target like 'yahoo' or whatever, note that the host have to be 
# reachable every time
target="www.yahoo.com"

# log file
file="/var/log/updown.log"

# your routers here
router1="192.168.0.1"
router2="192.168.0.254"

# default router
default=$($ip route | awk '/default/ { print $3 }')

# ping command
ping -c 2 ${target}

if [ $? -eq 0 ]; then
   echo "`date +%Y%m%d-%H:%M:%S`: up" >> ${file}

else
   echo "`date +%Y%m%d-%H:%M:%S`: down" >> ${file}

   if [ ${default}==${router1} ]; then
       ${route} del default gw ${router1}
       ${route} add default gw ${router2}
   elif [ ${default}==${router2} ];  then
       ${route} del default gw ${router2}
       ${route} add default gw ${router1}
   fi
   # sending a notification by mail or may be by sms
   echo "Connection problem" |mail -s "Changing Routing table" ${mail}
fi

答案 3 :(得分:3)

我喜欢William的回答,因为它不需要民意调查。所以我根据他的想法实现了以下脚本。它解决了控件必须返回shell的问题。

#!/bin/sh

someproc()
{
        sleep $1
        return $2
}

run_or_timeout()
{
        timeout=$1
        shift

        {
                trap 'exit 0' 15
                "$@"
        } &
        proc=$!

        trap "kill $proc" ALRM
        {
                trap 'exit 0' 15
                sleep $timeout
                kill -ALRM $$
        } &
        alarm=$!

        wait $proc
        ret=$?

        # cleanup
        kill $alarm
        trap - ALRM
        return $ret
}

run_or_timeout 0 someproc 1 0
echo "exit: $? (expected: 142)"
run_or_timeout 1 someproc 0 0
echo "exit: $? (expected: 0)"
run_or_timeout 1 someproc 0 1
echo "exit: $? (expected: 1)"

答案 4 :(得分:1)

您可以执行以下操作,但不可靠:

#!/bin/sh

trap handle_timer USR1

set_timer() { (sleep 2; kill -USR1 $$)& }
handle_timer() {
    printf "%s:%s\n" "timer expired" "$(date)";
    set_timer
}

set_timer
while true; do sleep 1; date; done

这种技术的一个问题是陷阱在当前任务返回到shell之前不会生效(例如,用睡眠10替换睡眠1)。如果shell在大多数时间处于控制状态(例如,如果它调用的所有命令都将快速终止),则可以正常工作。当然,一种选择是在后台运行所有内容。

答案 5 :(得分:0)

创建一个bash脚本,检查互联网连接是否已关闭,并在每60秒运行一次的crontab任务中添加脚本。