2011年6月19日 星期日

[ linux ] time 時間控制

在 linux 下使用 shell script,
要進行一些定時的動作,雖然沒有辦法像 c 直接摳 lib準給你看~
但也是有一些做法啦~~

下面是我使用的方法、有土法煉鋼的感覺XD

首先是用 date 來叫系統的時間,標計不同動作之間所花費的時間。
再利用 sleep 把剩下的時間花掉。
這裡 sleep 的時間是變數。會隨著每次執行時,經過不同時間標計,跟欲停等的時間相減。

這樣就可以讓程式更精確的掌握時間。

date 指定輸出時間,可以使用 %N 輸出位數到達 ns (雖然極限還是要看系統本身)。
這樣就可以讓 sleep 時間更精細。

下面的例子是假設我執行一個動作,是 sleep $1 輸入的時間。
那我想要每十秒做一次。
t1, t2 是兩個不同時間的標計
那 t3就是用來計算剩下來,要等待的時間。

[root@local tmp]# cat time_test.sh
#!/bin/bash
time_step=10.0
t1=`date -u +%s.%N`
sleep $1
t2=`date -u +%s.%N`
t3=` echo "scale=9; $time_step-($t2 - $t1)" |bc -l`
sleep $t3
[root@local tmp]# for ((i=1; i<=3; i++)); do  time sh time_test.sh 2.222; done

real    0m10.015s
user    0m0.000s
sys     0m0.000s

real    0m10.017s
user    0m0.000s
sys     0m0.000s

real    0m10.017s
user    0m0.000s
sys     0m0.004s

上面用 time 來幫忙測試修正後的準度是多 0.015秒左右。


現在改成真實情況下~~~現在我要監況系統上 每秒鐘 page 的變化。


#!/bin/bash
while [ 1==1 ]; do
        tt=`date -u +%s.%N`
        #echo -ne "$tt"|awk 'BEGIN {FS="."} {printf $1 "\t" }'
        echo -ne "$tt\t"
        cat /proc/meminfo|awk '{ FS=" "} $1=="Dirty:"|| $1=="Active:"||$1=="Inactive:" {printf $1 "\t" $2 "\t" }'
        echo
        t2=`date -u +%s.%N`
        t3=`echo "scale=9;1-($t2-$tt)"|bc -l`
        sleep $t3
done
cat /proc 下的一些系統資訊
再 pipe 一個 awk  的指令,指定抓出 dirty, active, inactive page 容量的這三個資訊。
從結果看來,每次抓取 data 的時間可以控制在 0.005秒左右的時間誤差。



[root@root local]# sh view_page.sh
1308418954.922866000    Active: 528868  Inactive:       14413628        Dirty:  0
1308418955.927929000    Active: 528768  Inactive:       14413628        Dirty:  24
1308418956.932796000    Active: 528772  Inactive:       14413624        Dirty:  32
1308418957.937796000    Active: 528836  Inactive:       14413624        Dirty:  32
1308418958.942785000    Active: 528828  Inactive:       14413624        Dirty:  32
1308418959.947850000    Active: 528840  Inactive:       14413624        Dirty:  120
1308418960.952689000    Active: 528856  Inactive:       14413624        Dirty:  120
1308418961.957697000    Active: 528848  Inactive:       14413628        Dirty:  120
1308418962.962704000    Active: 528836  Inactive:       14413628        Dirty:  148
1308418963.967793000    Active: 528848  Inactive:       14413628        Dirty:  148
1308418964.972579000    Active: 528876  Inactive:       14413620        Dirty:  8




當然,這些都只是以現有的 bash 組合一些工具,盡可能的做出來。
我相信如果使用程式語言,應該還有更精確、嚴謹的作法~~~

改天有機會再研究嘍~~~~

沒有留言:

張貼留言