== Safely updating Unix files Tim Bray provides Apple [[some instructions http://www.tbray.org/ongoing/When/200x/2006/05/11/iCal-still-sucks]] on how to update files containing important data (like iCal calendars). His directions are fine at a high level, but they're actually not quite detailed enough to implement from. So here's how you safely update Unix files: # create a new scratch file in the same directory as the target file (ideally mode 0600). # write the data to it; optionally _fsync()_; optionally verify the data. # copy the current version's permissions to the scratch file. # ~~_link(2)_~~ the current version of the file to the backup file name. # _rename(2)_ the scratch file to the real filename. # _fsync()_ your ex-scratch file, now real file, again. (Add extra steps to taste if you want to keep more than one backup file.) The important bit, and the important difference, is the _link(2)_ and the _rename(2)_. This sequence insures that if the system crashes, no matter when, you will always have *some* version of the file around; you will never be left with _foo.old_ and _foo.new_ but no _foo_. (This guarantee is often important when doing updating things like system binaries or _/etc/passwd_.) For shell scripts, this is: > cp foo /etc/.newfile && \ > cmp -s foo /etc/.newfile && \ > ln -f /etc/foo /etc/foo.bak && \ > mv -f /etc/.newfile /etc/foo > sync I see a lot of shell scripts that leave out the _cmp_. I always think that they're being awfully optimistic about _cp_'s error handling. (Technically you should have a _sync_ between the _cp_ and the _cmp_ because that's the only insurance you have against physical disk errors on the write; what _cp_ has written has not necessarily hit the platters and thus run into any physical media problems by the time it exits successfully. Issues like this give paranoid sysadmins nervous tics.) I have omitted the step to synchronize permissions and ownership, because I don't know of a good utility to copy them from file A to file B.