I'd never heard of it. There's a writeup about it here, as well as a couple of blog entries (here and here)
Rather than go straight to mtree (I still have to read the man page), this is a write-up of the bash script posted on the the first blog post. So it's really more about improving my bash scripting-fu (origin here) than it is about mtree.
> nl script.sh 1 #!/bin/sh 2 SCRIPT="`basename $0 | sed 's/\..*$//'`" 3 CONFIG=${1:-$HOME/.$SCRIPT} 4 DIR=${2:-$HOME/Documents} 5 cd $DIR || \ 6 { echo "Failed to change working directory to $DIR" >&2; exit 1; } 7 if [ -f $CONFIG ]; then 8 /usr/sbin/mtree -f $CONFIG 9 fi 10 /usr/sbin/mtree -c -k time,md5digest,ripemd160digest > $CONFIG> |
I added line numbers with nl, you could use cat or other methods.
I hope line 1 is obvious (see wikipedia if it's not).
In line two, we take the variable $0, which is the path to the script, obtain its basename, and then strip off the extension:
> basename /Users/telliott/script.sh script.sh > echo x.txt | sed 's/\..*$//' x |
I had an even harder time with lines 3 and 4, but the folks on StackOverflow helped me.
I learned that bash has a man page (of course!). Also that one can search within a man page by entering "/ :-" after you get the page, which initiates a search for ":-". The answer:
${parameter:-word}
Use Default Values. If parameter is unset or null, the expansion
of word is substituted. Otherwise, the value of parameter is sub-
stituted.
So these two lines
3 CONFIG=${1:-$HOME/.$SCRIPT} 4 DIR=${2:-$HOME/Documents} |
simply give default values for $CONFIG and $DIR if we don't supply them as arguments ($1 and $2) when invoking the script. If we called the script by ./script.sh from the Desktop, then we'd have $CONFIG be equal to ~/.script (a hidden file) and $DIR be equal to ~/Documents.
Lines 5 and 6 change the working directory to ~/Documents as default, if this fails (because the path input as an argument is no good) we write a message to >&2 and exit with 1 signifying failure. >&2 is stderr. This writes to the Terminal for me.
Lines 7 through 9 check whether $CONFIG exists already, if it does then we call mtree with the -f flag and $CONFIG argument:
/usr/sbin/mtree -f $CONFIG
From the mtree man page:
-f file
Read the specification from file, instead of from the standard
input.
If this option is specified twice, the two specifications are com-
pared with each other, rather than to the file hierarchy. The
specifications be sorted like output generated using -c. The out-
put format in this case is somewhat remniscent of comm(1), having
"in first spec only", "in second spec only", and "different" col-
umns, prefixed by zero, one and two TAB characters respectively.
Each entry in the "different" column occupies two lines, one from
each specification.
But the first time through, $CONFIG shouldn't exist yet. Instead, we call mtree with the -c and -k flags followed by various arguments, and write the result to $CONFIG. Let's do it in a simple way, as shown below. From the Desktop directory I input the command as shown, and write the results to x.txt in $HOME. As you can see, timestamps for all the Desktop files are there:
/usr/sbin/mtree -c -k time > x.txt > cat ~/x.txt # user: telliott_admin # machine: Toms-Mac-mini.local # tree: /Users/telliott_admin/Desktop # date: Mon Apr 23 17:20:21 2012 # . /set type=file . type=dir time=1335216020.0 .DS_Store time=1335216014.0 .localized time=1333333575.0 notes.txt time=1335210868.0 post.txt time=1335216020.0 script.sh time=1335215494.0 script.sh.txt \ time=1335211653.0 todo.txt time=1335204803.0 .. > |
Now, if I do it with -f, I get:
> /usr/sbin/mtree -f ~/x.txt . changed modification time expected Mon Apr 23 17:20:20 2012 found Mon Apr 23 17:20:51 2012 .DS_Store changed modification time expected Mon Apr 23 17:20:14 2012 found Mon Apr 23 17:20:55 2012 post.txt changed modification time expected Mon Apr 23 17:20:20 2012 found Mon Apr 23 17:20:51 2012 |
I see a change because I'm writing this text into post.txt! For some reason .DS_Store also changed. Next time I'll try to do something a little more useful.