50 Setting the System Date


#50 Setting the System Date

Conciseness is the heart of Unix and has clearly affected its evolution in quite a dramatic manner. However, there are some areas where this zeal for succinctness can drive a sysadmin batty. One of the most common annoyances in this regard is the format required for resetting the system date, as shown by the date command:

 usage: date [[[[[cc]yy]mm]dd]hh]mm[.ss] 

Trying to figure out all the square brackets can be baffling, without even talking about what you do or don't need to specify. Instead, a shell script that prompts for each relevant field and then builds the compressed date string is a sure sanity saver.

The Code

 #!/bin/sh # setdate - Friendly front end to the date command. # Date wants: [[[[[cc]yy]mm]dd]hh]mm[.ss] askvalue() {   #  = field name,  = default value,  = max value,   #  = required char/digit length   echo -n " [] : "   read answer   if [ ${answer:=} -gt  ] ; then     echo " 
 #!/bin/sh # setdate - Friendly front end to the date command. # Date wants: [[[[[cc]yy]mm]dd]hh]mm[.ss] askvalue() { # $1 = field name , $2 = default value, $3 = max value, # $4 = required char/digit length echo -n "$1 [$2] : " read answer if [ ${answer:=$2} -gt $3 ] ; then echo "$0: $1 $answer is invalid"; exit 0 elif [ "$(( $(echo $answer  wc -c) - 1 ))" -lt $4 ] ; then echo "$0: $1 $answer is too short: please specify $4 digits"; exit 0 fi eval $1=$answer } eval $(date "+nyear=%Y nmon=%m nday=%d nhr=%H nmin=%M") askvalue year $nyear 3000 4 askvalue month $nmon 12 2 askvalue day $nday 31 2 askvalue hour $nhr 24 2 askvalue minute $nmin 59 2 squished="$year$month$day$hour$minute" # or, if you're running a Linux system: # squished ="$month$day$ hour $minute$year" echo "Setting date to $squished. You might need to enter your sudo password:" sudo date $squished exit 0 
: $answer is invalid"; exit 0 elif [ "$(( $(echo $answer wc -c) - 1 ))" -lt ] ; then echo "
 #!/bin/sh # setdate - Friendly front end to the date command. # Date wants: [[[[[cc]yy]mm]dd]hh]mm[.ss] askvalue() { # $1 = field name , $2 = default value, $3 = max value, # $4 = required char/digit length echo -n "$1 [$2] : " read answer if [ ${answer:=$2} -gt $3 ] ; then echo "$0: $1 $answer is invalid"; exit 0 elif [ "$(( $(echo $answer  wc -c) - 1 ))" -lt $4 ] ; then echo "$0: $1 $answer is too short: please specify $4 digits"; exit 0 fi eval $1=$answer } eval $(date "+nyear=%Y nmon=%m nday=%d nhr=%H nmin=%M") askvalue year $nyear 3000 4 askvalue month $nmon 12 2 askvalue day $nday 31 2 askvalue hour $nhr 24 2 askvalue minute $nmin 59 2 squished="$year$month$day$hour$minute" # or, if you're running a Linux system: # squished ="$month$day$ hour $minute$year" echo "Setting date to $squished. You might need to enter your sudo password:" sudo date $squished exit 0 
: $answer is too short: please specify digits"; exit 0 fi eval =$answer } eval $(date "+nyear=%Y nmon=%m nday=%d nhr=%H nmin=%M") askvalue year $nyear 3000 4 askvalue month $nmon 12 2 askvalue day $nday 31 2 askvalue hour $nhr 24 2 askvalue minute $nmin 59 2 squished="$year$month$day$hour$minute" # or, if you're running a Linux system: # squished="$month$day$hour$minute$year" echo "Setting date to $squished. You might need to enter your sudo password:" sudo date $squished exit 0

How It Works

To make this script as succinct as possible, I use the following eval function to accomplish two things.

 eval $(date "+nyear=%Y nmon=%m nday=%d nhr=%H nmin=%M") 

First, this line sets the current date and time values, using a date format string, and second, it sets the values of the variables nyear , nmon , nday , nhr , and nmin , which are then used in the simple askvalue() function to prompt for and test values entered. Using the eval function to assign values to the variables also sidesteps any potential problem of the date rolling over or otherwise changing between separate invocations of the askvalue() function, which would leave the script with inconsistent data. For example, if askvalue got month and day values at 23:59.59 and then hour and minute values at 0:00:02, the system date would actually be set back in time 24 hours, not at all the desired result.

This is one of various problems in working with the date command that can be subtle but problematic . With this script, if you specify the exact time during the prompts but you then have to enter a sudo password, you could end up setting the system time to a few seconds in the past. It's probably not a problem, but this is one reason why network-connected systems should be working with Network Time Protocol (NTP) utilities to synchronize their system against an official time-keeping server.

Learn more about network time  

You can start down the path of network time synchronization by reading up on timed(8) on your system.

Running the Script

Notice how this script uses the sudo command to run the actual date reset as root . By entering an incorrect password to sudo , you can experiment with this script without worrying about any strange or unexpected results.

The Results

 $  set-date  year [2003] : month [07] : day [08] : hour [16] : minute [53] :  48  Setting date to 200307081648. You might need to enter your sudo password: passwd: $ 



Wicked Cool Shell Scripts. 101 Scripts for Linux, Mac OS X, and Unix Systems
Wicked Cool Shell Scripts
ISBN: 1593270127
EAN: 2147483647
Year: 2004
Pages: 150
Authors: Dave Taylor

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net