Unix Shell Script Checking BST/GMT

A problem over the last weekend when the clocks went forward, showed there was a need to do resolve to how the GMT cron jobs should work on a few servers working together (when timing is important).

For a couple of years I simply changed the hour in the crontab on each server and left it at that, but alas this is open to error across multiple severs, so I decided to do something about it.

The first step was to put the cron table into GMT hours (i.e. ensure all jobs would run as GMT as normal). The next step was to introduce for the “morning run” of work, a check to sleep for an hour if the server is in British Summer Time (BST). We can find this out by using:

date

Which can give an output like this:

Mon Apr  1 12:17:55 BST 2013

All we want is the local time zone daylight savings flag and then do something if that is BST. We can get just this flag if we use the %Z parameter to the date command.

Here’s a little bit of code to wait if we’ve run in GMT but need to wait an hour due to BST:

# --- GMT checking - we assume run in GMT timeframe
SLEEPPERIOD=3600
GMTBST=`date '+%Z'`
if [ $GMTBST == BST ]
then
        # must be in summertime, so wait an hour
        echo "Found the date has $GMTBST. Sleeping for $SLEEPPERIOD seconds ..."
        sleep $SLEEPPERIOD
else
        echo "Not BST, carrying on"
fi

This is then done for the afternoon run and the same again for the evening run.

Note this may cause a problem if multiple scripts check this as they may get serial delays. This works best if you have one main job, and the check is done once.

So now the script will check if it is GMT or BST and wait an hour if BST.

Simple Shell Script – File if-then-else

Problem

An annoyance with one of my Raspbery Pi computers is that the two USB weather stations it is connected to sometimes lose USB connectivty and appear on a different file handle. The USB port (either /dev/ttyUSB0 or /dev/ttyUSB1 then re-enuermates on a different file handle in the /dev folder.

Aside from fixing the issue in the firmware or kernel on the Pi (being investigated), a temporary fix is to restart the Pi when /dev/ttyUSB2 appears.

Solution

The soultion used is to have a script that checks if a new USB file handle appears and then reboot if that happens. We also need to check every five minutes if this happens because the weather station sends reports every 10 minutes and we need to ensure that it continues to do that in time.

So, that means a cron job and a shell script and here they are …

Shell Script (check-usb.sh)

Here’s the script in full:

 #!/bin/sh
 LOGFILE=/home/pi/cgi-bin/log/check-usb.log
 USB0=/dev/ttyUSB0
 USB1=/dev/ttyUSB1
 USB2=/dev/ttyUSB2
 USB3=/dev/ttyUSB3
 TIMENOW=$(date)

 if [ -e "$USB0" ] && [ -e "$USB1" ]
 then
  echo "$TIMENOW: $USB0 and $USB1 found"
  echo "$TIMENOW: $USB0 and $USB1 found" >> $LOGFILE
  echo "$TIMENOW: Exit normally"
  echo "$TIMENOW: Exit normally" >> $LOGFILE
  exit 0
 fi
# If get to here check for others
 if [ -e "$USB2" ] || [ -e "$USB3 ]
 then
  echo "$TIMENOW: $USB2 or $USB3 found"
  echo "$TIMENOW: $USB2 or $USB3 found" >> $LOGFILE
  echo "$TIMENOW: USB re-numerated - reboot required"
  echo "$TIMENOW: USB re-numerated - reboot required" >> $LOGFILE
  /sbin/reboot
 fi

A log file is also included as that’s a useful diagnostic tool – don’t forget to use logrotate to chop it from time to time. The key bit is to do a shell if using -e to see if the file handle to the USB device is still there. As there are two USB devices to worry about (two file handles), use a logical or to ensure they are both there. Otherwise, something is broken so then do a reboot having logged that fact to the log file for later review.

Right, that takes care of the checking, now the cron job.

Cron Job

I set this to run as a root cron job (crontab -e to put this in your cron table for root). This ensures no problems with permissions and also means that root is rebooting and not anyone else.

#check every 5 mins if USB 0 or USB 1 get re-enumerated
#if USB0 or 1 disappears reboot to resync
*/5 * * * * /home/pi/cgi-bin/check-usb.sh

That should get around the problem until a patch is available for the loss of USB enumeration.

PHP: using from the shell command line (use php-cli)

A long-running project uses PHP for the somewhat slow creation of some databases tables and dynamic javascript arrays.

The shell script that calls the PHP uses curl to make the scripts work. Alas the hosting provider offers a shared service and the PHP scripts often time out.

A way to run your scripts that rely on HTTP $_GET, is to use php-cli as the engine and not the normal PHP processor. In this way, you can test your PHP scripts from the command line as if they are pulled using HTTP.

Be aware that this needs to be enabled for your system and that there is normally a separate php.ini file for it.

The original post has gone, but more info here.

PHP: Dynamic Day List of Weather URLs

Not sure how to dynamically list days in the future on fixed URLs?

A recent problem arose when trying to provide a dynamic list of linked URLs on a page based on the textual name rather than the numeric date (see right). A number of sub-pages on a website has unique, but not ordered URLs, suffixed with a page number (numeric). It is easy to simply statically list them, but why not dynamically put them in ascending order? Find out how to do it here.