Wednesday, May 4

Back in Colorado, the lawn needs mown and the sink is full of dishes. Last Tuesday morning’s old-computer build is still half-assembled on the kitchen floor and the kitchen counters and probably several other places.

There are a bunch of things I should be doing (like the dishes), but I was just dorking around with some pointless shell script instead.

It got me thinking about how it’s too hard to write little shell utilities. Two categories of reason for this:

First, the existing shells are bad as general-purpose programming languages.

  • The simple things you want from a language are either missing or really hard to get.
  • The syntax is hideous and everything is riddled with edge cases which will bite you or your users.
  • Patterns exist to help with some of this, and conscientious authors will be aware of them, but they are inconsistently applied, made of illegible boilerplate, and often a matter of unevenly-distributed folklore.
  • I’ve evidently been harping on this one for a while.

Second, general-purpose language environments are bad at the stuff I want when I write shell utilities.

  • Argument handling is miserable and full of boilerplate.
  • Doing things to files and directories is way harder than it should be.
  • The “correct” abstraction around a given task is often much harder to use than the corresponding shell utility would be.
  • The best available library often introduces a new (and sometimes unstable) dependency.
  • Reusing other parts of the shell environment is often fraught with hazard, or at least silliness.

I don’t want to claim these plaints are universals, exactly.

There are glue-language features in Perl which keep me coming back for little one-offs that wind up in my ~/bin/. I wrote a thing in Python the other day using docopt to handle arguments, and hey, really, not too shabby. Despite its problems, there are encouraging things about some of the patterns I see used in Node.js.

I would, however, still like to see an improved toolset for the conceptual space of “little things you use at the command line”.

I learned the other day that you can do this:

brennen@exuberance 21:45:01 /home/brennen ★ cal -3
       April                  May                   June
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
                1  2   1  2  3  4  5  6  7            1  2  3  4
 3  4  5  6  7  8  9   8  9 10 11 12 13 14   5  6  7  8  9 10 11
10 11 12 13 14 15 16  15 16 17 18 19 20 21  12 13 14 15 16 17 18
17 18 19 20 21 22 23  22 23 24 25 26 27 28  19 20 21 22 23 24 25
24 25 26 27 28 29 30  29 30 31              26 27 28 29 30

…which will show the months before and after the current one.

I don’t know how I made it this long without knowing about that option. There’s a generalized approach, too, with -B n and/or -A n for n months before and after the current month.