Some years back I wrote a book titled The Art of Unix Programming. My goal in that book was to convey the Zen of Unix to today’s generations of eager young Linux and *BSD programmers. In the spirit of that book, I feel impelled to point out out a program I’ve recently learned as a striking, near-perfect example of Unix style in the modern day. rsnapshot, you’re doing it right!
rsnapshot is a filesystem snapshot utility for making backups of local and remote systems; you save your stuff with it. I can describe it pretty well by just listing the ways that it fulfills classic Unix design patterns.
1. Everything the program does is driven by a single configuration file in a plain-ASCII text format – easily readable by the Mark One Eyeball, easily editable without special tools.
2. The configuration file is a specification in a declarative minilanguage. That is a bit different and stronger statement than point 1; it implies that, rather than being a series of tweaks of opaque parameters that cannot be understood without intimate knowledge of the rsnapshot code, the configuration is largely self-describing given a certain fairly minimal understanding of the application’s domain (making backups).
3. rsnapshot delegates everything it can and doesn’t reinvent wheels. The actual backup engine is rsync, possibly assisted by ssh (two bog-standard Unix tools every sysadmin will have installed). Backup scheduling is handled by putting rsnapshot jobs in a cron file. Notifications to the sysadmin are done through normal email.
4. While high performance of the backup engine is important (and rsync is tuned for it) performance of rsnaphot itself is not. So it’s written in a scripting language for best flexibility and maintainability. Perl wouldn’t have been my first choice, but for this application it is a big win over C or any compiled language.
5. rsnapshot doesn’t have a GUI because it doesn’t need one; the real “interface” to it is a text editor running on its config file. If somebody wanted to give it a GUI, the GUI code could be a separate small program that simply does structured modifications of the config file while remaining completely isolated from the logic of rsnaphot itself. Such separation lowers global complexity, reduces bugs, and increases the options to improve both programs.
6. Mechanism is clearly separated from policy. In this particular case, the portions of the configuration language that describe the tools to use for doing backups are clearly separated from scheduling and the specification of archive locations.
7. rsnapshot run on a config file with a syntactic or other detectable error emits a useful error message including the line number of the error to standard error. The real point is that errors lead to more understanding rather than some bland “A problem occurred” pointing nowhere in particular.
8. rsnapshot includes a -t (test) option that allows you to see the rsync and other copy commands a given configuration would emit without committing them. It also includes a -V option to show more detail about how these actions were generated. These options, especially in combination with the previous point, make the program discoverable; they lower the cost of becoming familiar with it.
9. rsnapshot makes as few wired-in assumptions as it can get away with. This future-proofs it against, for example, changes in the preferred backup tools. If rsync were to be obsolesced by a faster and better file-tree-synchronization tool tomorrow, rsnapshot installations would be using it without fuss the next day.
10. rsnapshot isn’t just good, it’s unobtrusively good. The design doesn’t repeatedly hit you over the head with how clever it is or try to impress you with flashiness signifying nothing. It is spare, clean, elegant, and gets out of your way. This is correct Unix style!
I’m not saying rsnapshot is absolutely perfect – I could quarrel with the reliance on tabs as field separators in the config file, even though the parser is helpful about telling you when you’ve used the wrong kind of whitespace. But it’s near perfect, and a worthy model for programmers trying to improve their Unix style.