Hacker News new | past | comments | ask | show | jobs | submit login
Watch – A Useful Linux Command You May Have Never Heard Of (beerpla.net)
126 points by geoka9 on Oct 26, 2010 | hide | past | favorite | 57 comments



How many times did I want to watch a directory waiting for a file to appear in it?

For this sort of thing I use a simple perl script called atchange. I could do:

   atchange . ls
And I'd see list output whenever a new file appeared in the directory. The hacky thing I usually use it for:

   atchange my_source_file make
to make things rebuild when I save my_source_file in my editor.

The script is here: http://www.ccrnp.ncifcrf.gov/~toms/ftp/atchange The webpage about it is here: http://www-lmmb.ncifcrf.gov/~toms/atchange.html

I first learnt about it years ago while reading the entertaining ``Work'' Columns by Jeffreys Copeland & Haemer: http://alumnus.caltech.edu/~copeland/work/


You can do something similar on OS X using Kicker (http://github.com/alloy/kicker), which is based on the FSEvents library.


Much better, because its doesn't keep spamming you even when nothing has changed so far.


I was thinking you could pipe watch into uniq, but then you wouldn't get any results until you killed it. The hexdump utility has adjacent duplicate line detection, and something similar would be trivial to create.


Or just let the kernel tell you via inotify http://en.wikipedia.org/wiki/Inotify


Sort of, on Linux. See my comments elsewhere on this page for an inotify "replacement" of atchange, and notes on why it won't do quite the same thing as the perl script.


A nitpicky thing, but kudos to the post author for including the word "may" in the title.

I'm not sure if my ego is being stoked or bruised, but it irks me every time I see a post like "10 Commands You've Never Heard Of"... and it's either a list of esoteric commands used by low level coders or commands that have fallen out of favor over the years.

And I'm familiar with every one of them. I've seen this round of knowledge cycle full circle a couple times now. I can't imagine the eye rolling of neckbeards who've been around professionally since the 80s.


What happens is someone will read 30 blogs on blogging that say "hey lists are awesome," then whip up a random list without much thought, expecting fame and fortune.

It only works if you're either exceptionally clever, or are passing out some original information.


It seems like the normal readership are drawn to these kinds of list posts. Perhaps because they are "busy" and want to learn quickly by absorbing information nuggets. I question that they actually learn anything.

MSNBC (and by extension, their advertisers) has really been taking advantage of it by drawing readers to their many recent "top ten" lists.


Well there's different kinds of lists. A list could be a bunch of bullet points and <= 3 sentences each, or a narrow list of 3-5 where a lot is covered in each.

The latter can be extremely informative and provide a good starting point for someone. The former is filler.


That's exactly how I felt about this too, and therefore included the word "may."

I was wondering what the hell was going on with comments on that page today, before looking at the stats: http://i.imgur.com/tVhwK.png


For the problem of watching the last lines of something: a few options, you can pipe to tac, e.g.

  watch 'ls -l | tac'
which reverses the lines of the output, or if it is something like a log file, you can forget about watch completely and just use tail -f, e.g.

  tail -f logfile.log
which will print new lines as they are added to the file.


ls -lr


Well, checking when your directories and files change should be a job for some inotify based tool, not periodically launched ls, sadly, inotify based version of common unix utilities are still very optional and hackish, not found in the base distro.


Thanks! When I first used atchange (detailed in another comment) I saw mention of things like inotify, but didn't have the kernel support on the system I was using.

Fast-forwarding to now, having just installed inotify-tools (Debian/Ubuntu package):

   while true; do inotifywait . &> /dev/null ; ls ; done
is a much more responsive version of:

   atchange . ls
I should probably make a wrapper that uses inotify when available and degrades to atchange's brute force approach when necessary.


To resemble the atchange script, try this usage of inotifywait:

  while true; do inotifywait -qq -e modify [filename]; [command]; done
or as a shell function, defined in .bashrc to have the same form as the atchange perl script:

  function atchange(){
    while true;
    do inotifywait -qq -e modify $1;
    $2;
    done


Thanks. Below is the version I'm trying. It allows multiple-argument commands, doesn't stomp on atchange if inotifywait isn't installed and I wanted it to fire when touching files as well as modifying them.

  if which inotifywait > /dev/null ; then
      function atchange(){
          FILE="$1"
          shift
          while inotifywait -qq -e modify -e attrib "$FILE"; do
              "$@";
      done;}
  fi
Looking again at atchange it deliberately waits after first noticing the file has been modified, in case something is still modifying it. It fires once writing has stopped for at least a second. I'm not sure if I need that in my use cases, but its authors clearly did so I'm pointing out that the above shell function does not provide a true like-for-like replacement. (Also atchange allows a single argument to be a command_file, functionality I never use.)

EDIT changed the "while true" so that the function stops on an error rather than infinitely looping when something goes wrong, like FILE ceasing to exist. A file temporarily disappearing would scupper the script though, whereas the perl script deals quietly with that.


I use 'watch' to continuously run my suite of unit tests. I write a new test, it starts failing while looping under 'watch', then I write code to make it pass.


I have used it for ram memory (free) and processes (ps) monitoring.


Doesn't top do the same job?


I use watch continuously for just about everything.

watch -n 1 "ps aux | grep something"

watch -n 1 "killall some-runaway-process"

etc


This would've been better as a simple link to a man page, I think.


I think the article does a better job of explaining why you might want to use watch than man watch does.


Really? What part of the article was more useful than the man page?

  diff the-article the-man-page | wc -w
  => 75


Well then, I guess it must be the 75 words.


The summary of those 75 words is "I want to watch for file changes but am too lazy to write a Perl script. Look at this. `man watch`"

I guess we just disagree about what part of the post is useful.


Hm, is there a similar command for this on the mac (that is installed by default)?

I looked around and this is all I could find: http://www.sveinbjorn.org/watch_macosx

I have a bunch of while loops written in bash, but would prefer something cleaner.


You can install it using MacPorts.


Just this week I found the program "gorun" which does this. Unlike watch, gorun does not poll. It uses inotify. http://github.com/peterbe/python-gorun


I use something like this to watch the processes that are running or waiting for IO

  watch -n 1 ps -eo pid,ppid,wchan=WIDE-WCHAN-COLUMN,stat,command r


Nice. However, it doesn't account for activity during the gap between samples, while sorting by CPU usage in top or by I/O usage in iotop does.


What an awful name for such a tool. Unix commands have the command as subject, not the user (examples: ls, find, make, touch, shutdown). From the name and the 'ls' example, I expected something that reacted to file system notifications, but this doesn't watch, it repeats a command, clearing the screen before every iteration.


You're watching the output of a command. In what world exactly, is the name 'watch' unclear or a poor choice?


I think the person you're responding to felt that Unix command should describe what you're telling the computer to do: "ls" makes the computer list files, "find" makes the computer find things, "echo" makes the computer echo what you give it, etc.

"watch" does not make the computer watch anything (at least in its default mode of operation); it makes the computer run a command repeatedly and the user watches it. "repeat" or "refresh" might have been more consistent names.


Yes, that is what I was complaining about. An alternative, consistent with 'at', could be 'every':

  *every 2s ls*

  *echo "ls" | every 5m
For readability, I would then drop the default for the time interval; the command without the time interval (every ls) reads awfully.

And yes, that first way of specifying what to repeat is different from the way at does it. I am not sure I would want to follow 'at' in that respect.


It looks like watch is usually used on Linux. watch(8) for FreeBSD is something totally different.

http://www.linuxquestions.org/questions/*bsd-17/linux-watch-... gnu-watch, cmdwatch, gnuwatch etc.


For the impatient, watch takes decimals:

  watch -n .2 <cmd>
and it'll go every .2 seconds


A couple of months ago, I was doing some nasty shell hacking, and I came across 'tsort'. It is of limited utility in my day to day existence, but when I needed it, I really needed it. Thanks, whichever hacker decided it should be a standalone utility!


Context: tsort is a topological sorter, which is nice for handling & finding loops in dependency graphs.

IIRC there's an example in _The Awk Programming Language_ implementing a toy make out of a topological sorter. (Edit: pgs. 170-8.)


Right, I should have said.

EDIT: Topological sorting is one of those tools that really comes in handy -- it's easy enough to implement, but I didn't want to spend the time either (a) writing it in zsh or (b) rewriting the rest of the shell pipeline in Python or something. 'tsort' to the rescue! I just wish I could remember where I read about it so I could go buy whoever was at the other end of the Google search a beer.


If you want to see which mysql queries are running in almost-realtime, you could do:

  watch -n 1 -d 'echo "SHOW PROCESSLIST;" | mysql'


You might find mytop easier for this, it also allows hiding sleeping processes etc.


Good tip. Thank you for pointing this out.


It's a GNU command rather than "Linux". Does anybody care or know the difference?


I was wondering if it was required by SUS, and it doesn't look like it: http://www.opengroup.org/onlinepubs/9699919799/ . On my system running the Ubuntu distribution of GNU/Linux, it is provided by the procps package, with homepage at http://procps.sourceforge.net/ . I grabbed the source and had a look and there's nothing that says that it's part of GNU, nor are is the copyright owned by the FSF. Contrast this with the GNU coreutils, which mention GNU specifically in the README and have the FSF named as the copyright holder in the source files. There's very little to suggest that it's a GNU package, although calling it a "Linux" command is still technically inaccurate, I suppose, even if everyone knows what you mean. It seems to me to be like other common abuses of notation, such as saying f(x) = O(x) as opposed to f(x) \in O(x).


Nitpick: f(x) \in O(x) is still an abuse. f \in O(id) would be better. Or f \in O(fun x -> x). Where f \in (R -> R).


Noted. Thanks.


Well, it's not GNU, and it is written for Linux. So, I think calling it a Linux command is OK.


while 1; do ls; sleep 5; done


Watch has a nice difference flag, so that whatever is different from the last iteration is highlighted. As in:

watch -d sudo netstat -tnp


Closer to watch -

  while 1; do datetime; ls; sleep 2; done


I used to do:

  while true; do date; ls; sleep 2; clear; done
but got tired of it and searched apt for watch.

  apt-get install procps


I used to do:

  while true; do date; ls; sleep 2; clear; done
but got tired of that and installed procps via apt.


1: command not found


try this instead:

while true; do ls; sleep 5; done


Is there an equivalent syscall for this?


Ah, the larval stage, how cute.

When I want to monitor a directory, I let the kernel tell me via inotify.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: