Usul: non-POSIX tabular Unix utilities
Today I pushed
usul to GitHub. Usul is a suite of non-POSIX replacements for the standard Unix command line utilities, designed to fix a number of problems POSIX enforces in the name of backwards compatibility. As an example, let’s take
ls, which happens to be one of the very few utilities I’ve written so far. POSIX demands that the output of
ls -Rl look something like this:
total 16 drwxr-xr-x 3 cls cls 102 4 Jan 2012 colors -rw-r--r-- 1 cls cls 261 28 Jun 23:04 gvimrc -rw-r--r-- 1 cls cls 1104 28 Jun 23:10 vimrc ./colors: total 16 -rw-r--r-- 1 cls cls 7765 4 Jan 2012 molokai.vim
This is absolutely terrible if you want to do something with this information, like pipe it somewhere. We have these pointless “
total 16” headers which we have to
grep -v out of the way to begin with, then we have two different formats for timestamps depending on whether they’re older than six months or not, and… don’t even get me started on the “
./colors:” format for recursing directories. Seriously. Now, Usul has output that is much more useful for piping around:
drwxr-xr-x cls cls 2012-01-04 14:36 colors/ -rw-r--r-- cls cls 2012-01-04 14:36 colors/molokai.vim -rw-r--r-- cls cls 2012-06-28 23:04 gvimrc -rw-r--r-- cls cls 2012-06-28 23:10 vimrc
Each of those double spaces is actually a tab, which are field separators, and the line feeds are record separators, à la
Well, it turns out that we have a totally separate utility called
find, with an argument syntax totally unlike any other, largely for the reasons shown above. So we can use
find to recursively list those directories, but if the paths contain a line feed we have to use
find -print0 to separate files with
NUL bytes instead of line feeds (which isn’t even in POSIX), and then we’ll need
xargs -0 to read it again, but no other tools support that so we’ll probably end up creating some monstrous
find query and the Unix philosophy is dead.
All Usul utilities use the environment variables
RS, field and record separators, just as
find . -print0 is just the same as
ls -R with
FS= RS=, but all utilities (e.g.,
grep) would understand that the records are separated by
NUL bytes, not just
xargs. They are all ‘tabular’, so you don’t have to waste time coercing output from one program to another.
Another thing Usul does well is just having generally sane behaviour.
ls -Rd will do what you expect, only
ls -Ra will recurse into hidden directories, and so on. It’s also very pedantic about avoiding race conditions. Anyway, I’ll be quietly getting on with these. It’s mostly for my own benefit, but someone else might find them useful, too.