Most Unix system administrators, when needing to compare two or more
files to determine if they are the same or different, will use the diff
command. When used on text files, diff will report the differences in
the two files and will prepend lines in the report with < and > marks to
indicate which file contains each of the displayed lines. The diff
command will also annotate the listing with terse remarks such as "1a2"
or "10c10" that mean such things as "add line 2 to file 1" and "replace
line 10 in file 1 with line 10 from file 2. These strings are meant to
express how the differences in the two files can be rectified.
diff abc abcd
1a2
> extra line of text
For binary files, diff simply reports that the files are different or,
to indicate that the files are the same, reports nothing at all.
The drawback of the diff command is that it requires all of the files to
be compared to be on the same system. When the files to be compared are
on different systems, an easier way to compare them is to generate a
checksum on each of the systems and compare the checksums. Since the
same checksum algorithm is used by the cksum command on each of the two
systems, the result of the operation should be the same.
By using cksum in this way, we avoid any need to copy files from system
to system merely to compare them with other files. Checksums work as
well as they do both because the algorithm is generally ubiquitous and
because a difference as small as a single byte will result in a very
noticeable change in the checksum, making it very hard to miss.
Another interesting use of the cksum command is to compare the output of
two commands. If you are running a command that generates a large amount
of output on one system, you can reduce the output to a checksum by
piping it like this:
$ myprogram | cksum
This will generate a checksum on all output directed to standard out.
If you run the same command on another system, you can do the same thing
and then compare the checksums from the two systems to determine whether
the process produced the same output on each of the two systems.
Complex and lengthy output, such as the output generated by a make
command used to compile a large program, might otherwise be very
difficult to compare. The more output, the more likely it is that small
differences in the output of two runnings will be overlooked. Reduced to
a checksum, the comparison is nearly instant.
Of course, you're likely to want to preserve the output from the command
you have run - at least until you have verified that you have the result
that you expected. To generate a checksum while preserving the original
output, you can do something like this:
$ myprogram | tee -a /tmp/output$$ | cksum
Then, if the checksum does not match the data you are comparing it
against, you can investigate further by combing through the output saved
in /tmp/output$$.
The cksum command generally reports three pieces of information: the
checksum itself, the length of the file or output that is being
evaluated, and the name of the file.
$ cksum to_do_list.txt
1207020748 2948 to_do_list.txt
When used against data coming from standard in, only the first two
pieces of information are reported since no file is involved. To see
how this works, you can run some common commands and send their output
to cksum. Here are some examples:
$ ls -l | cksum
3737176896 2305
$ df -k | cksum
2172816462 1142
df -k | cksum
2172816462 1142
As an aside, whenever I get the same response from the "df -k | cksum"
twice in a row, I know that everyone else in the office has gone home
for the day. Otherwise, subtle changes in the space used and available
columns in the df output would yield a dramatically different response
from one second to the next.