Code / Watch

Save History Patch for Watch

Cut to the chase, download here


We've all had times where we've needed to sit there, running a command over and over, checking the output each time to see if something has changed. Many times it's as simple as watching a file copy or download, using the "ls -l" command every so often to check the progress. Well, someone came along and wrote a utility to help with that called "watch". If you've never used it, you've been deprived of a wondeful utility, and you owe it to yourself to look into it.

If you have used watch, you'll most likely have run into the problem that you don't like squinting at your terminal in order to catch what's changed. Watch offers a "--differences" option that takes some of the pain out of keeping track of differences, because it highlights the things that have changed between invocations of the command given to it to run. The differences option has an optional parameter of "cumulative". This option will make the changes sticky so that anything that changes will stay highlighted until you exit.

The problem (a.k.a. the itch)

In true open source fashion, I had an itch to scratch. You see, I needed to keep track of changes that were made to a database, but I needed to see these changes over the course of a 24 hour period, and I didn't just need to see that my record count changed, but WHEN it changed, and WHAT it changed to. Using --differences by itself was useless, because unless I was sitting there watching it, I wouldn't catch the difference when it happened. Adding cumulative to the mix didn't help either, because at the end of the run, it would tell me that the record count changed, but I already knew it would. What I needed was the ability to watch the command, and snapshot the differences when they would happen, so that I could track through the history and correlate what happened with my test run and what the output was of the command I was running at that specific time.

The solution (a.k.a. the scratch)

While I can admit that I didn't look terribly hard, I really didn't find much out there in the sense of what I needed. What I needed was a modification to the watch utility. I didn't need any fancy bells and whistles, I just needed it to do a screen dump on every time it saw a change.

The solution became obvious. I had a utility already. I had the source. It wasn't a terribly complex utility, so hacking in my changes should have been quite easy. For the most part, it was. What my labor produced was another option called "--save-history". Save-history basically does what I mentioned I needed: at each time the utility detects a change in output, it dumps the screen into a text file. Each screen dump comes with a header that contains the command line used, as well as a timestamp of when it did this particular dump.

The default behavior is to put all the changes into one large text file, but dreadn0t reminded me that it's damn impossible to diff one large file, and unless you cut it into chunks it may be useless. He suggested offering an option to dump each screen as a file of it's own, timestamped in the name. This was the birth of the --multifile option. Multifile uses the same history file you handed to --save-history, but it uses the path and name as a prefix, and tacks on the date and time to it to create a unique file name. For example, if you do this:

watch -d --save-history /tmp/dumps/watching_you -m "ls -l"

You'll get a set of files named watching_you-yyyy_mm_dd-hh:mm:ss in /tmp/dumps.

That's about all there is to it. If you want to build this, you'll need to get the original package (linked above) and copy the file into it. Run "make", and even "make install" if you feel so inclined.