LJDT: The 'watch' command
Do you ever find yourself running a command, pressing the up-arrow, then [Enter], then the up-arrow, then [Enter], then the up-arrow…. this is a great exercise that will get your fingers used to typing random odd key sequences without your eyes paying attention, but otherwise it’s a complete waste of time. A command I have come to love helps me point my OCD tendencies to other pointless tasks while running commands over and over for me. Introducing ‘watch’, because Linux Just Does That.
The first time this command saved my life was when I ran a command and had to wait several seconds to several minutes for a port to start listening for incoming data. A LAN trace would not satisfy the task… I had to use netstat over and over and over just to see if the TCP port would ever listen properly (no alternatives for seeing the list of open ports at the time). So off I went with the following command:
#get the output from netstat -anp (all output, numerically, showing process information for anything that is found so I know what is actually using each socket), #then redirect away any errors because I'm not 'root', and finally grep for 'LISTEN ' which gets me just TCP output. netstat -anp 2>/dev/null| grep 'LISTEN '
Up-arrow, [Enter], up-arrow, [Enter]…. eventually I broke down and wrote a really dumb loop:
#Same as above, once per second. while [ 1 ] ; do netstat -anp 2>/dev/null | grep 'LISTEN ' sleep 1 done
This worked well enough, but it made my screen scroll indefinitely and it still required the ability to write a loop. So somebody pointed out a command called watch which, surprisingly enough, lets you “watch” the output of a command over time. Give it an interval and away you go:
#Same as above, but easier and nicer formatting.
watch --interval=1 "netstat -anp 2>/dev/null | grep 'LISTEN '"
The output is something like the following:
Every 1.0s: netstat -anp 2>/dev/null | grep 'LISTEN ' Tue Sep 22 13:46:02 2009 tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN - tcp 0 0 :::111 :::* LISTEN - tcp 0 0 :::22 :::* LISTEN - tcp 0 0 ::1:631 :::* LISTEN -
Another example is watching for a file to change sizes. When waiting for an application to write something to a file the same thing applies… either I can use the up arrow to its destruction or I can just watch the output of a terminal that is regularly refreshed.
watch --interval=1 'ls -l /path/to/some/file.log'
Notice that not only does it show the output (once, not over and over), which is nice, it actually shows the command that is running, how often it is running, and a current timestamp indicating the last time the command was executed (within the last second or so with this particular command). By default ‘watch’ runs the specified command every two seconds instead of every one, but I need that up-to-the-second output at least. The command(s) specified can be fairly elaborate and anything executable on the system. Like a good command it works within a ‘screen’ so you could have one of these running perpetually watching for certain data in certain files and then acting based on that which you could connect/disconnect to/from as often as you would like. The ‘watch’ command comes with the ‘procps’ package on SUSE which is the same one that brings a few other useful tools to users including but not limited to ‘ps’, ‘w’, ‘vmstat’, ‘free’, and ‘pgrep’.
There are other ways to write little ‘watch’-like applications as shown above but this is obviously something others stumble upon and want to do regularly so to do it the quick/easy way use the right tools. Loops are decent tools, but a command that meets your exact need is a great tool and having a wide array of great tools is what Linux Just Does.