simple script to set system clock


Forum: Programming and Scripting
Topic: simple script to set system clock
started by: newOldUser

Posted by newOldUser on Feb. 17 2007,17:18
Here's the background.... I have an old machine running DSL that I use as a server for various projects.  I reboot it every month or so to check the hard drives. I've noticed that after a few days the time starts go a little wonky. Just a little bit more each day.  

So I was looking for something that I could automatically run each day to set the time.  There were some good suggestions on the forum about installing an NTP client. I'm sure it's probably easy to do and works fine but I decided to try my hand at writing a script to do it.

It's not as acurate as an NTP client but it's close enough for what I need and it will work in native DSL.

Code Sample


#! /bin/bash
version="1.00"
scriptName="getTime.sh"
#
# This script gets time information from time.nist.gov in
# universal time format. It then rearranges it into
# the format that the date command uses MMDDhhmmCCYY.ss
# and issues the date command as super user.
#
# An internet connection must be available
#
#  sample of returned information follows
#54144 07-02-13 16:14:43 00 0 0  95.3 UTC(NIST) *
#0----0----1----1----2----2----3----3----4----4----5
#0----5----0----5----0----5----0----5----0----5----0
#
vFound=""
telnet time.nist.gov 13 > nistTime.txt
date
vFound=$(cat nistTime.txt | grep "UTC(NIST)")
if [ ! -z "$vFound" ]; then
    vDateTime=${vFound:9:2}${vFound:12:2}${vFound:15:2}${vFound:18:2}"20"${vFound:6:2}"."${vFound:21:2}
     sudo date -u "$vDateTime"
     #echo "$vDateTime"
fi
date



I thought about setting the hardware clock also but then that might mess people up who dual-boot to windows.

One thing that I wasn't able to solve was setting the telnet timeout.  How long the script waits trying to connect to time.nist.gov if my internet connection is down or if time.nist.gov is down?  I'd like to be able to set a timeout parameter of 15 seconds but I don't see how. Anyone know how to change it?

-Enjoy

Posted by ^thehatsrule^ on Feb. 17 2007,18:37
You could kill that process if there's no easy timeout solution...

Or you could do something like a test ping of that site first, before you proceed with the rest of the script.

Posted by roberts on Feb. 18 2007,05:46
Reading this script and a request for how to handle timeout, made me think of such capability using Lua sockets.

So, just for fun, I cobbed together this little Lua socket program.

It is working well for me. I run it manually prefixed with sudo.
I did not call date using sudo as in newOldUser's original, as I call this lua program from /opt/bootlocal.sh

Now when I boot my machine, I have a much more accurate clock set.

You can see socket level programming is at a lower level than calling bash functions. But it does provide much more control.

Code Sample
#! /bin/lua
--[[
# This lua script based in part of the idea expressed in
# the bash script from newOldUser of the damnsmall linux forums
# by Robert Shingledecker - 2007/02/17
# This script gets time information from time.nist.gov in
# universal time format. It then rearranges it into
# the format that the date command uses MMDDhhmmCCYY.ss
# and issues the date command as super user.
#
# An internet connection must be available
#
#  sample of returned information follows
#54144 07-02-13 16:14:43 00 0 0  95.3 UTC(NIST) *
#1---0----1----1----2----2----3----3----4----4----5
#1---5----0----5----0----5----0----5----0----5----0
#
--]]
host = "time.nist.gov"
port = 13
target = {10,13,16,19,7,22}
date = ""

timeserver,err = socket.connect(host,port)
if err then
  print("Could not connect "..err)
  os.exit(1)
end
_,err = timeserver:send("anything\n")
if err then
  print("Error in sending "..err)
  os.exit(1)
end
timeserver:settimeout(0.10)
while 1 do
  line,err = timeserver:receive('*l')
  if err then
     print("Error in receiving "..err)
     os.exit(1)
  end
  if string.find(line,"UTC") then
     for i = 1, 6 do
        if i == 5 then date = date .. "20" end
        if i == 6 then date = date .. "." end
        date = date .. string.sub(line,target[i],target[i]+1)
     end
     os.execute("date -u "..date)
     os.exit(0)
  end
end



Posted by WDef on Feb. 18 2007,12:25
One idea inspires another.

Off-topic, but good to see you around Newolduser :=)  I thought you'd vanished off the forum!

Posted by newOldUser on Feb. 18 2007,14:40
^thehatsrule^, thanks for the suggestion... I hadn't thought about doing a ping first. It's funny how my mind gets locked into doing something one way and other solutions get blocked.

Roberts, neat stuff... One of these days I'm going to learn LUA.

WDef,  Sorry about being offtopic... I'm never sure where to put these things that I write.  I have one or two other scripts that I need to pretty-up so I can share them. I had been putting them in the blogs but there are problems putting code in the blog area.  

I was gone for a while, but still using DSL. I've come back to find that we're up to version 3.something and all my machines are at version 2.3 or below.  Since I usually do a frugal install I'm hoping that upgrading will not be too difficult. I'm sure there are plenty of forum entries that will help me. :)

Posted by humpty on Feb. 20 2007,15:08
it looks like telnet needs sudo too;

...
sudo telnet time.nist.gov 13 > nistTime.txt
vFound=$(cat nistTime.txt | grep "UTC(NIST)")
if [ ! -z "$vFound" ]; then
   vDateTime=${vFound:9:2}${vFound:12:2}${vFound:15:2}${vFound:18:2}"20"${vFound:6:2}"."${vFound:21:2}
   date -u
   time1=`date +%s`
   sudo date -u "$vDateTime"
   time2=`date +%s`
   timediff=`expr $time2 - $time1`
   date
   echo corrected by "$timediff" seconds
fi

P.S/
umm,, how do you update this to the fluxbox toolbar ?

Posted by mikshaw on Feb. 20 2007,17:05
If your commands are in a script, you can simply run the script as sudo rather than adding multiple sudo commands to the script.

If fluxbox is not automatically updating, just restart it. You don't need to restart x if this is done from the Fluxbox confguration submenu, so you won't lose your open applications.
I think it will update itself if you wait a bit, but i'm not sure about that.

If your script is run from bootlocal (assuming your network is set up automatically), both issues should be handled already.

Posted by humpty on Feb. 20 2007,18:53
quite right mikshaw. easy way to force the fluxbox update is to right-click near it so the menu covers it, then left-click on empty space. :)
Posted by newOldUser on Feb. 21 2007,00:33
Hmmmmm.... interesting..... I don't have to do an sudo telnet.

The machine I wrote this for has a frugal install of DSL version 2.2    I'm not sure why I don't need an 'sudo telnet'

Posted by humpty on Feb. 21 2007,10:08
Quote (newOldUser @ Feb. 21 2007,07:33)
I'm not sure why I don't need an 'sudo telnet'

maybe you don't. just that whenever i don't use sudo, the telnet just hangs there..(?)
Posted by roberts on Feb. 21 2007,14:52
I have updated my Lua script so that the NIST timeserver can be specified and also the initial connection timeout defaults to 5 seconds but can be user specified as well.

Code Sample
#! /bin/lua
--[[
This lua script based in part of the idea expressed in
the bash script from newOldUser of the damnsmall linux forums
by Robert Shingledecker - 2007/02/17

Usage: sudo gettime.lus {nist_time_server} {timeout-in-secs}

See: http://tf.nist.gov/service/its.htm

This script gets time information from an NIST time server
in universal time format. It then rearranges it into
the format that the date command uses MMDDhhmmCCYY.ss
and issues the date command.

An internet connection must be available

 sample of returned information follows
54144 07-02-13 16:14:43 00 0 0  95.3 UTC(NIST) *
1---0----1----1----2----2----3----3----4----4----5
1---5----0----5----0----5----0----5----0----5----0
--]]

host = arg[1] or "time-nw.nist.gov"
port = 13
timeout = arg[2] or 5.00
target = {10,13,16,19,7,22}
date = ""

timeserver = socket.tcp()
timeserver:settimeout(timeout)
_,err = timeserver:connect(host,port)
if err then
  print("Could not connect "..err)
  os.exit(1)
end
_,err = timeserver:send("anything\n")
if err then
  print("Error in sending "..err)
  os.exit(1)
end
print("Requesting time from: "..host)
timeserver:settimeout(0.50)
while 1 do
  line,err = timeserver:receive('*l')
  if err then
     print("Error in receiving "..err)
     os.exit(1)
  end
  if string.find(line,"UTC") then
     for i = 1, 6 do
        if i == 5 then date = date .. "20" end
        if i == 6 then date = date .. "." end
        date = date .. string.sub(line,target[i],target[i]+1)
     end
     os.execute("date -u "..date)
     os.exit(0)
  end
end


Please choose a timeserver nearest to you so that we all don't gang up on one. See the URL embedded for a list.

Posted by WDef on Feb. 21 2007,21:21
Quote
WDef,  Sorry about being offtopic


No, no you misunderstand!  It was ME that was offtopic - I was posting about not seeing you 'round the forum for a while!  I don't think there's anything 'offtopic' about your post.  I wasn't clear I know.

Anyway - keep up the scripting, let's see the other efforts :=)

Powered by Ikonboard 3.1.2a
Ikonboard © 2001 Jarvis Entertainment Group, Inc.