#!/bin/sh -u # Answer file: Exercise #4 - moreweather.sh # show changes in temperature/pressure/visibility/humidity for a city #------------------------------------------------------------------ # Syntax: $0 [ city_code [ weather_item ] ] #------------------------------------------------------------------ # Purpose: # Display the current temperature/pressure/visibility/humidity for a # given city. Print the result in a nice, readable format. # # Every hour, re-check the weather item and print a line only if # a change has occurred in the weather. (No change means no output.) # If the current user ($USER) is not online, the script stops # looping, prints a message, and exits. # # Prompt for any missing arguments if standard input is a terminal. # If not a terminal, a missing city code defaults to "YOW". # If not a terminal, a missing weather item defaults to "temperature". # Note: This script is not intended to be used as a CGI script; # since, it outputs no CGI header and errors print to standard error. #------------------------------------------------------------------ # Student Name: Ian Allen # Algonquin EMail Address: alleni # Student Number: 074-210-779 # Course Number: DAT2330 # Lab Section Number: 010 # Professor Name: Ian Allen # Assignment Name/Number/Date: Exercise #4 due November 30 # Comment: This is a sample solution. #------------------------------------------------------------------ # Set a standard shell search path and a friendly umask. # PATH=/bin:/usr/bin ; export PATH umask 022 #------------------------------------------------------------- # Input section. # Exit the script if more than two arguments are supplied. # if [ $# -gt 2 ]; then echo 1>&2 "$0: Expecting city code and weather item; found $# args ($*)" exit 1 fi # The user might have entered 0, 1, or 2 arguments. # Prompt for missing arguments if standard input is a terminal. # Use defaults for missing arguments if no terminal. # if [ $# -eq 0 ]; then if tty -s ; then echo 1>&2 "Enter city code and weather item:" read citycode weatheritem || exit $? else citycode=YOW weatheritem=temperature echo "Using default city code $citycode and weather item $weatheritem" fi elif [ $# -eq 1 ]; then citycode="$1" # first arg is citycode if tty -s ; then echo 1>&2 "Enter weatheritem:" read weatheritem || exit $? else weatheritem=temperature echo "Using default weather item $weatheritem" fi else # we must have exactly two arguments on the command line # citycode="$1" # first arg is citycode weatheritem="$2" # second arg is weatheritem fi # #------------------------------------------------------------- #------------------------------------------------------------- # Input validation section. # Count the characters in the city code; make sure there are three. # Subtract one to account for the newline at the end of the line. # count=$( echo "$citycode" | wc -c ) let count=count-1 if [ "$count" -ne 3 ] ; then echo 1>&2 "$0: Expecting 3-character city code, found $count '$citycode'" exit 2 fi # Check for one of the four weather items we know how to fetch. # Choose a search pattern based on the item. # Exit if the item is not one of the four we accept. # if [ "$weatheritem" = "temperature" ] ; then pattern="Temp.:" elif [ "$weatheritem" = "pressure" ] ; then pattern="Pressure:" elif [ "$weatheritem" = "visibility" ] ; then pattern="Visibility:" elif [ "$weatheritem" = "humidity" ] ; then pattern="Humidity:" else echo 1>&2 "$0: Unknown weather item '$weatheritem'" echo 1>&2 "$0: Expecting temperature, pressure, visibility, or humidity" exit 3 fi # #------------------------------------------------------------- #------------------------------------------------------------- # Processing and output section. # # Make the city code UPPER CASE. # citycode=$( echo "$citycode" | tr 'a-z' 'A-Z' ) # Loop as long as $USER is logged in: # Fetch the page for the city code. # Look for the string "Error" in the fetched page and exit if found. # Extract the weather item and the city name. # Note: the fields may have many extra blanks around them still. # Note: looking for ": Issued" fails for some weather pages. # If the old value is not the same as the new value (value has changed): # Generate nice output with multiple blanks squeezed down to one. # Copy the current value to the old value. # Wait a while before repeating the loop. # url="http://weatheroffice.ec.gc.ca/forecast/city_e.html?$citycode" oldvalue='' # starts as empty, so weather prints first time through loop sleeptime=3600 # 60*60 seconds -> an hour # sleeptime=10 # un-comment this to DEBUG this script while who | grep "$USER" >/dev/null ; do page=$( lynx -dump "$url" ) if echo "$page" | grep "Error" >/dev/null ; then echo 1>&2 "$0: Cannot find weather for city code '$citycode'" exit 4 fi value=$( echo "$page" | grep -e "$pattern" | awk -F: '{print $2}' ) # value=$( cat testvalue ) # un-comment this to DEBUG this script cityname=$( echo "$page" | grep -e "Issued" | awk -F: '{print $1}' ) if [ "$oldvalue" != "$value" ] ; then echo "$(date) The $weatheritem in $citycode - $cityname - is $value" \ | tr -s ' ' fi oldvalue="$value" sleep "$sleeptime" done echo "$0: Cannot find '$USER' logged in - script exits" # script exits with return status of last command executed