(Show changes between two AFS trees)


frak [-CDhLmqsv] [-c changedir] [-d max-diff-lines] [-l logfile] (volume | rw-path [ ro-path ])


frak is a tool for comparing the structure and contents of two directory trees in AFS. Its most common use is to determine the changes in a read/write AFS volume relative to the read-only copy of the same volume, to ensure that it's safe to release, but it can be used to compare any two arbitrary AFS trees. It can even be used in a limited fashion to compare non-AFS trees, although in that case diff -r may be more appropriate.

frak understands mount points and directory ACLs and will detect changes in those as well as more typical changes in file size, permissions, or existence. It also knows not to cross mount points (unless given the -C option). Note that two files with the same permissions and the same size will be considered identical; the file is not actually compared with diff if its other information matches.

If two files are different and are determined to be text files (using the -T probe in Perl; see perlfunc for more information), diff -u will be run on the two files. This output will be included in the frak output provided it's less than 100 lines long (controllable with -d). Otherwise, just the length of the diff in lines will be given. Diffs can be suppressed completely with -s.

The paths to compare may be specified in three ways. A volume name can be given as the sole argument (distinguished from a path by the fact that it doesn't contain a /). In this case, the read-only and read-write versions of that volume will be mounted in the current working directory (so the current working directory must be in AFS), as frak-volume and frak-volume.readonly, and then compared. A path may be given as the sole argument, in which case it is taken to be the path to the read-write version of the tree and should begin with /afs/.. It will be compared against the read-only path to the same tree, formed by removing the period after /afs/. Or, finally, two paths may be given, and they will be taken to be the read-write path (the newer tree) and the read-only path (the older tree) respectively. Please note that this is the exact opposite order from what one would pass to diff.

If a volume is specified, frak will by default log the output to a file named after the volume in the current directory, as well as printing the output to standard output. To suppress the file log, use -L. To suppress the output to standard out, use -q. The name and location of the log file can be changed with -l. If a path is specified, frak will by default only print to standard output. To also log to a file, specify a log file location with -l. In either case, the log file will be overwritten if it already exists.

If a volume is specified, paths in the output will be shown relative to the root of the volume. If a path is specified, paths in the output will be complete paths unless -m is given. If -m is given, paths will be relative to the root of the tree specified by the path given on the command line.

The name frak comes from the swear word used in Battlestar Galactica, which should give you some ideas about the origin of this program.


-C, --cross-mounts

Normally, frak will never cross a mount point. If this option is given, it will keep comparing through mount points. Be careful when using this option, since frak will happily recurse through all AFS file systems in the world, and remember that circular path structures are possible in AFS. frak does no checking to make sure that it doesn't revisit the same volume endlessly.

-c changedir, --change-dir=changedir

When given this option, frak creates three bundles changedir, as well as directories named new and old. The first bundle is named changes.b, which if run will populate the new and old directories with all of the files that have changed between the two trees. The second bundle, revert.b, will use those files to revert the changes to the read-write path so that it matches the read-only path. The third bundle, apply.b, will reapply the changes to the read-write path so that it returns to the state that it was in before frak was run.

The intended use of this feature is to make it possible to back out arbitrary changes made to the read-write path of a volume, release the volume, and then put those changes back. Please note that this feature is not as well-tested as the rest of frak, and the bundles should be reviewed very carefully before use. Note also that frak can be used again after revert.b has been applied, to make sure that the read-write volume really does match the read-only volume.

This option only really makes sense when used with a path, rather than a volume, on the command line. Otherwise, the bundles will use paths relative to the temporary mount points created by frak, which isn't as useful.

-D, --debug

Display additional debugging information. This is mostly only useful for debugging frak.

-d max-diff-lines, --max-diff-lines=max-diff-lines

Limit the number of lines of diffs shown for changed files to max-diff-lines. The default is the value of the $FRAK_MAXDIFF configuration variable, which in turn defaults to 200. Diffs with longer than that number of lines will be replaced with a message saying how many total lines the diff had.

-h, --help

Print out this documentation (which is done simply by feeding the script to perldoc -t).

-L, --no-log

Suppress the default logging to a file that occurs if a volume rather than a path is specified on the command line. The output will only be sent to standard output.

-l log, --log-file=log

Log the frak output to log as well as to standard output. If a volume was specified on the command line, this overrides the default log file name (the name of the volume). If a path was specified, this enables logging to a file.

-m, --munge

Only meaningful when a path was specified on the command line. Tells frak to show paths in the output relative to the top of the tree specified on the command line, rather than showing absolute paths.

-q, --quiet

Suppress the normal output to standard output. frak output will only be sent to the log file, if any.

-s, --suppress-diffs

Suppress diffs for changed files. This also turns off the check to see if changed files are binary or text, and will make frak run somewhat faster.

-v, --version

Print out the version of frak and exit.


frak loads configuration settings from /etc/afs-admin-tools/config if that file exists. If it exists, it must be Perl code suitable for loading with require. This means that each line of the configuration file should be of the form:

    our $VARIABLE = VALUE;

where $VARIABLE is the configuration variable being set and VALUE is the value to set it to (which should be enclosed in quotes if it's not a number). The file should end with:


so that Perl knows the file was loaded correctly.

The supported configuration variables are:


The default limit on the number of diff lines that will be included. This should be a number. The default value is 200. This setting is overridden by the -d command-line option.


The full path to a diff implementation that supports the -u option. If this variable is not set, frak defaults to using the first diff program found on the user's path.


The full path to the AFS fs utility. If this variable is not set, frak defaults to looking for fs on the user's PATH.


The full path to the AFS vos utility. If this variable is not set, frak defaults to /usr/local/sbin/vos or /usr/sbin/vos if they exist, and otherwise looks for vos on the user's PATH.


Compare the read-write and read-only copies of the volume pubsw, mounting both in the current directory to do the comparison, and putting a copy of the output into the file pubsw in the current directory:

    frak pubsw

Do the same, but store the output in /tmp/pubsw.log:

    frak -l /tmp/pubsw.log pubsw

The same, but don't print anything other than errors to standard output:

    frak -q -l /tmp/pubsw.log pubsw

The same, but only print the output to standard output:

    frak -L pubsw

Compare the path /afs/ to /afs/, printing the output to standard output.

    frak /afs/

A completely equivalent way to do the same thing:

    frak /afs/ /afs/

Do the same, but log the output to /tmp/pubsw.log:

    frak -l /tmp/pubsw.log /afs/

Compare the read-write and read-only copies of the volume pubsw, writing the change bundles into the subdirectory changes of the current directory:

    frak -c changes /afs/

One can then cd to the changes directory and run changes.b, and then revert.b to revert the changes to the read-write path. At some point later, one could run apply.b to replace the changes.


Originally written by Neil Crellin <>. Substantially reorganized and rewritten by Russ Allbery <>.


Copyright 1998, 1999, 2004, 2011 The Board of Trustees of the Leland Stanford Junior University.

This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.


bundle(1), diff(1)

This script is part of the afs-admin-tools package. The most recent version is available from the afs-admin-tools web page at <>.

bundle, for the --change-dir feature, is available from <>.

Last spun 2014-08-10 from POD modified 2014-04-14