"I cannot explain what I am doing, but you must allow me to continue."
Friday, August 18, 2017
User Login

Sign in below:

Username:
Password:
Entries of Interest

Recent entries:

Register to read:

  • I've missed you, too, baby.
Links
Useful and interesting:

Missing "watch" on OSX - a fast and easy watch implementation in bash

Posted on Saturday, February 23, 2013 at 10:32am (PST)


Working in OSX, I found that at least some earlier versions appear not to have any version of "watch" installed by default. For an admin or engineer, watch is an indispensable tool that allows you to run commands at intervals and observe the results. For more information about watch in Linux, check out the man page.

So in working with OSX, I found pretty quickly I needed a replacement for this functionality. There are packages available for OSX that you can install, but if you'd rather not have to spend the time verifying someone else's package, you can duplicate some of the functionality of watch by using the bash function below. It does not have all the abilities that a full watch implementation would have (the only flag it accepts is '-n' for the interval), but it worked well for my use case to watch changes on the filesystem.

To use this implementation of "watch," place the following function in your ~/.bash_profile:

function watch () {

command=""
interval=""


    function showusage() {
    printf '%s\n%s\n\n' "Usage: watch [-n seconds] command" \
     "Seconds must be a positive number (default 2 if unspecified)"
    }

case $1 in
  -n | --seconds )
    interval=$2
    shift 2
    ;;
esac

command=$*


if [ -z "$interval" ]; then
    interval=2;
fi

if [ -n "$(echo $interval | grep [^0-9\.])" ] || [ $interval -le 0 ]; then
    showusage
    return -1
fi

if [ -z "$command" ]; then
    showusage
    echo "Error: You must enter a command to watch as the last argument."
    return -1
fi

starttime=$(date +%s)

while :;
do
    timestamp="$(date +%s)"
    commandstring="Every $interval seconds: \"$(echo $command)\""
    startstring="Watch start: $(date -j -f '%s' $starttime +%c)"
    durationstring="Elapsed: $(( $timestamp - $starttime )) seconds"
    let COL1=$(tput cols)-${#commandstring}
    let COL2=$(tput cols)
    clear
    printf "%s%${COL1}s\n" "$commandstring" "Current time: $(date -j -f '%s' $timestamp +%c)"
    printf "%${COL2}s\n" "$startstring"
    printf "%${COL2}s\n\n" "$durationstring"
    eval $command
    sleep $interval;
done
}

Remember that you will then need to open a new terminal or source your ~/.bash_profile in order to use the function.

Hopefully this function is useful for others who are looking to create a fast and easy watch implementation in OSX. If this was useful for you (or not), feel free to send me some feedback via email or using the web form.

Related Media: None.

Keywords: OSX; command line; watch


Previous:April 21, 2012