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 2016 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.