Unshelled

I’ve spent the last couple of posts dissecting a shell script, one of my most popular posts is about shell scripting, and yet I really hate shell scripting.

I was thinking about this last night as I added updates to this small rewrite of Marco Arment’s feed subscriber counting script. Then this morning a tweet arrived from John Siracusa:

@drdrang Just say no to shell scripting.
  — John Siracusa (@siracusa) Sat Sep 29 2012 8:18 AM CDT

John is, famously, a Perl programmer, and Perl programmers tend to believe that every shell script could be shorter, clearer, more portable, and written faster if it were a Perl script. For was it not Larry Wall himself who spake:

It’s easier to port a shell than a shell script.

As someone who spent about a decade programming in Perl, I can’t say I disagree with this anti-shell point of view.

The Unix toolbox is so beguiling, so powerful, that it’s easy to start out thinking you’ll just pipe a few commands together and the script will practically write itself. And it does… at first.

But then comes the point—not always, but often enough—where you realize that to make the script truly useful you’ll need to add branching or looping. And if you’re like me, this is the point at which you curse yourself for starting it as a shell script.

Should I be using single square brackets or doubled square brackets? Or is it double parentheses? Is this where you can’t have a space after the opening bracket or where you absolutely must have a space after the opening bracket? Is this the place where you need that stupid semicolon between the if and the then? I know for loops don’t end with rof and do blocks don’t end with od, so why do if blocks end with fi?

Now I’m sure I’d be able to remember these things if I wrote more shell scripts, but that’s the problem: I don’t, and I don’t think I ever will. The shell just doesn’t have the numerical tools or data structures I need in my normal work, so I don’t get the practice in shell scripting that get in Python (and used to get in Perl). But it’s not just the lack of practice. Shell syntax for things other than simple pipelines is just plain weird—not like other languages and not obvious in and of itself.

Perl probably is the best of both worlds when it comes to cobbling together shell-like scripts. Its backticks allow you to commandeer Unix commands and pipelines when that makes sense, but it also has better math, regular expression, data structure, and branching and looping support.

So why didn’t I redo the the feed subscriber counting script in Perl? Well, first, I just wanted to tweak it a little, not rewrite it from scratch. Second, it didn’t have any looping or branching, so I never reached that “oh shit” moment. Finally, it seemed wrong to make such huge changes to someone else’s script.