posix shell is all you need

· erock's devlog

and a better line editor

I've been spending my free time reading the various specifications that I implicitly lean on daily for my software dev.
Recently it has been the posix spec.
In our pico.sh irc channel we've been idly chatting about what we like from our shells as well as exploring the variants that have spawned over the decades. It kind of crazy to think that some of these shell implementations have existed for that long. As I was exploring the annals of shell history along with own shell journey, I started to realize something: I really only care about the line editor experience. Bash has gnu readline, zsh has zle, fish has the "reader." This is where most of the user experience and innovation is coming from; these are the features I care about. I tried using the fish language for scripts, but it's not that much better and you lose a lot in terms of portability.
What I really care about in a shell is the line editor UX
I want good completions, an fzf like completion menu, auto-suggestions (e.g. ghost text completion), and an easy way to configure my prompt.
As an aside, I have to acknowledge that completions are a double-edged sword. I like reducing my tool usage to the absolute core "game loop". Completions are a form of shell lock-in and I do wonder if relying on them is an anti-pattern. I'm still chewing on what an alternative completions system could be.
It's funny, in order to build out those features you must first build a scripting language. What's worse, is that now with LLMs there's a kind of shell lock-in because they are so heavily trained on bash scripts, they make writing them trivial. Previously, the bash scripting language was foriegn enough that people -- like myself -- gave up on trying to understand them.
Well, this is where my posix journey has taken me: learning the bash syntax. In particular, I wanted to learn the difference between what is specified in the posix shell spec and bash. There are features, like the double-square bracket and support for arrays, and then a lot of subtle differences. I actually didn't know that bash has a posix mode and many linux distros symlink bash to sh. For example, arch symlinks bash to sh. Apparently, bash knows when argv[0] is `sh` and then runs `bash --posix`. Interesting, I always wondered why argv[0] was the command.
bash posix mode
It seems like even the various sh implementations are not perfectly compliant. As I was taught in econ, we live in a world with mixed systems, nothing is in its ideal form. Toast in chat mentioned yash which was attempting to be the most posix compliant shell, which piqued my interest.
https://magicant.github.io/yash/
It has the base posix sh compliance, with extensions for things like double-square brackets. It has UX features like auto-suggest (they call it auto-predict), completions, and a minimal completion menu that I like. It checked all the boxes for me so I chsh to it and it has been my daily for a couple of weeks now.
Yash, more than anything else, has made me realize that all I really need is posix sh. I don't need any fancy scripting features because I can just target bash. The line editor UX is where the real innovation lives. I'm leaving out some very experimental shells like nushell which I don't want to diminish. But when it comes to what everyone is installing and using, the scripting language seems like a nice-to-have, but not the reason why I would chsh a shell.
Looking at the various shell implementations, you'd be lucky to have something posix compliant in less than 40k lines of code. That is a stagering level of complexity. Virtually all of it is revolves around the scripting language itself and figuring out what programs to execute, with what options, and in what order. The syntax can get very complex:
{ exec 3>>b; false < out; exec 4>&-; } >> a; ( true; printf '%s\n' two >&3; )
This is where people get stuck when building out new shells. They get stuck in supporting the language syntax. Instead, what we actually need is the ability to experiment with different line editors. We need the ability to wrap posix sh with a custom line editor.
So I was looking into what already exists here. I quickly found ble.sh which is a bash line editor. It is written in bash and manages to hack around readline in order to enhance bash's line editing ux. This seems totally reasonable but the hackiness kind of bothered me. I also don't particularly want to enhance bash, I want to enhance posix sh.
bash line editor
Then I discovered the pty-proxy. This type of program can wrap the shell and enhance the line editor.
https://docs.atuin.sh/cli/reference/pty-proxy/
https://github.com/StanMarek/ghost-complete
https://github.com/fentas/atty
Now we are getting somewhere. It just so happens that zmx is also a pty-proxy, very interesting. What if I built a new shell that simply applies a line editor on top of sh? This seems to check all the boxes of a new project for me. It seems like it could play nicely with zmx as well. I should be able to apply the smol-contract to it as well.
https://bower.sh/smol-contract
And so it begins, my next project, and it just so happens that I've already started.
#pico.sh @ libera
last updated:

We're all in the gutter, but some of us are looking at the stars.
-- Oscar Wilde

Subscribe to my rss feed to read more posts.