The paradox of POSIX
Back to Unix
The POSIX standard exists to provide a common environment across operating systems. It dictates a minimum set of features for programming, the command line shell, and a set of applications or commands to be made available to the user.
On the plus side, POSIX is one of the reasons we have a basic level of compatibility between Unix-like systems and beyond.
On the minus side, POSIX is also the reason we have bonkers default
output in 512 byte blocks from utilities like df and du.
Richard Stallman was instrumental in naming the standard POSIX (Portable Operating System-ix) rather than the committee-chosen name "IEEEIX".
Stallman also fought against those block sizes as well (rightly
arguing for 1024 (1KiB) as a more natural unit), and lost that
fight, but not before putting the weirdo 512 byte units behind an
environment variable named POSIX_ME_HARDER in GNU utilities.
Enough history. How has this compatibility standard played out in reality?
POSIX shell programming - a holy grail not worth chasing?
I’ve seen a lot hand wringing over the years about writing POSIX-compatible shell scripts. Since POSIX shell is so restrictive, people go to great pains to accomplish this.
But finding a system without one of the common shells like Bash or Korn or even zsh is super rare.
In my experience, the real problem is all of the other tools.
I’ve been moving from Slackware Linux to OpenBSD on several of my personal computers, I’ve had to make changes to a number of my scripts and aliases to accommodate the differences between flavors of the core utilities that fall under the POSIX umbrella. It turns out, I had been using a number of non-POSIX features without realizing it.
Sticking with POSIX shell couldn’t save me from that. And it’s not just between Linux and BSD. I’ve run into this between Linux distros as well.
I’m aware that there are amazing tools like shellcheck that can tell
you if you’ve strayed from POSIX, but I gotta say, needing a tool like
that for a script that is supposed to be saving me time, well, I feel
like we’re kind of losing the plot.
Instead, my solution has been to rewrite my shell tools in Ruby, which makes my life so much easier on several fronts. For one thing, Ruby is such a better language than shell that I usually end up adding some nice-to-have additional features while I’m at it.
But the enormous advantage of something like Ruby is that the language and core libraries that ship with it provide 90% of what I need in terms of functionality and I can count on Ruby having these features no matter what platform I’m on. I simply don’t have to worry about non-standard features and options anymore.
Every system I have encountered in recent times supports Ruby.
POSIX tools versus…Perl
I’ve said I’m writing all my scripts in Ruby now, but I have to admit, there’s a language that is even more ubiquitous, stable, and well-known in this space: Perl.
OpenBSD considers Perl to be one of the few core languages of the OS and it ships with a base system along with C and sh.
I may not care for writing in the language anymore, but I’ll be the first to admit that Perl 5 is a tool you can absolutely count on to have a specific set of features across just about every platform you can think of. Shell will fail you. The coreutils will fail you. But Perl 5 will be there and your scripts will run.
I think there’s a fascinating phenomena here: Perl 5 has reached a natural stasis. (It still gets new features and updates, but they are (always?) backward compatible.) By contrast, POSIX is an artificial cryogenic lock based on the state of tools more or less as they existed in 1988.
It’s not that you can’t learn the POSIX standard and carefully stick to it for every script you write. The question is: do you want to?
It seems far easier to me to learn a tool which has reached cross-platform stability through a natural process of refinement and simply being done.