Hacker News new | ask | show | jobs
by wahern 1947 days ago
> Ad astra per aspera.

And yet reliance on Bash extensions rather than doing it in pure POSIX shell. ;)

A quick skim suggests the biggest convenience is using local variables to make recursion easier. But it's fairly easy to implement push and pop routines to turn global variables into a stack. You could even name push "local" and keep much the same syntax. Better would be an indirect call function which saves and restores a set of global "registers" across invocations, avoiding the need for explicit pops in each function.

Many of the pattern matching parts can be easily replaced with the canonical "fnmatch" shell implementation[1], which uses a case statement to provide in-shell fnmatch(3) emulation. If that's not powerful enough, expr supports regular expressions, though while usually a built-in it's not necessarily so. In the absence of regular expressions it's usually sufficient to use parameter expansion facilities to split strings and use simpler glob pattern matching on the components.

Still very cool. If I get bored one day I might try refactoring to make it pure POSIX shell.

Because Linux distributions (not to mention containers) are increasingly removing common shell utilities like bc, if this were extended to arbitrary precision arithmetic it might even be legitimately useful! For similar reasons I've implemented a base64 encoder and decoder using mostly pure POSIX shell--still depends on od(1) or dd(1) so it can do proper binary I/O, but the low-level coding is done using shell arithmetic and POSIX looping constructs.

[1] See http://www.etalabs.net/sh_tricks.html

2 comments

I'm afraid I don't have the wherewithal to do this in the Bourne shell! An explicit call stack using those globals is a neat idea. Generally the [[ =~ ]] construct is my go-to for string parsing. Can you do everything you need with parameter expansion and string globbing alone (without turning on "extglob" swince that would be cheating)? Finally, is your encoder/decoder posted online?
"Because Linux distributions (not to mention containers) are increasingly removing common shell utilities like bc"

Hmm that sounds fair, but if you can't do something simple like get bc why would you expect to be able to get this?