4 ms·
I want a better shell but only in that I want a Bash-like language (with builtin Linux userland programs like mv, cp, etc.) that works across macOS, Linux, and
by eatonphil 5y ago
I want a better shell but only in that I want a Bash-like language (with builtin Linux userland programs like mv, cp, etc.) that works across macOS, Linux, and Windows. (I cannot reliably get Bash for Windows installed on every Windows device I own.)
I want this for cross-platform build scripts. I build a desktop app for Windows, mac and Linux. I don't want a different set of scripts in a different language for each platform.
And I don't want to write in Python or JavaScript or Ruby or Perl because they're all so much more verbose than Bash.
But Bash on its own isn't enough either. I need the same Linux userland commands to work the same way on Windows. Powershell has mv and cp but they don't work the same way or have the same flags.
I hacked together a version of this language in Python that operates line by line and massages the differences between things like mv and environment variables in Windows, macOS, Linux.
https://github.com/multiprocessio/datastation/blob/master/scripts/build.py https://github.com/multiprocessio/datastation/blob/master/sc...
Here's a sample script it can run:
yarn
setenv UI_ESBUILD_ARGS "--minify"
yarn build-ui
prepend "window.DS_CONFIG_VERSION='{arg0}';" build/ui.js
yarn build-desktop
prepend "global.DS_CONFIG_VERSION='{arg0}';" build/desktop.js
yarn electron-packager --overwrite --out=releases --build-version={arg0} --app-version={arg0} . "DataStation Community Edition"
zip -r releases/{os}-{arch}-{arg0}.zip "releases/DataStation Community Edition-{os}-{arch}"
But this is a massive hack. So I'm starting work on a real language that supports a reasonable subset of Bash on Windows, macOS, and Linux and brings a reimplementation of the few key Linux userland commands (mv, cp, mkdir, rm plus new programs like append, prepend, replace, etc.) built into the interpreter.
A sketch of this more real version implemented in Go is here: https://github.com/multiprocessio/crosh https://github.com/multiprocessio/crosh. It doesn't build at all yet but if you're interested you can follow along.
- shagmin 5y agoHave you tried installing WSL2 and using a shell through that? Granted if Bash won't run on a machine reliably, WSL2 may not do much better on the same machine.
- eatonphil 5y agoYeah exactly. I cannot reliably get either WSL(1/2) or Bash for Windows installed on every device I own. It worked seamlessly on half of them and I can't figure out anything about why the others don't work at all.
- mixmastamyk 5y agoWhat does this mean? Maybe the cpu is old and doesn’t support virtualization? Hard to know without details.
- rzzzt 5y agoThis port of busybox might also suit your needs: https://github.com/rmyorston/busybox-w32 https://github.com/rmyorston/busybox-w32
- handrous 5y agoTruly, distributing more-than-trivial scripts (if trivial, just duplicate effort and have multiple scripts) cross-platform—including Windows—and to machines you aren't remote-adminning to fit your exact specs is hell, especially if some of the users aren't developers.
- eatonphil 5y agoThe use case is _build scripts_ for developer machines and automated builds. WSL2 is supported on Github Actions which is great. I'm the sole developer but again I just need these scripts to work across Windows and the other devices I need to test/develop on.
- AnIdiotOnTheNet 5y agoYou're not the first, nor do I expect you'll be the last, to reinvent the build scripting wheel. Things like this are why languages like Zig have decided that the build script language should just be the same as the actual programming language.
- eatonphil 5y agoTo be honest, just implementing bash as an educational project has been on my list for a while. Doing a cross platform subset is an even nice combo of learn something and keep my build scripts bash-y. Like I said I really don't want to make these scripts more verbose than bash and any other language would mean doing that.
- tnzm 5y agoThis is also why I advocate for JS as a scripting language (if it's already a part of your stack, anyway). Curiously, every time I mention it HN gets mad at me.
- BeetleB 5y agoHave you tried xonsh? It's cross platform, and while the language is Python, it is a modified Python so it's not nearly as verbose. You can write stuff like "cd directory" in your Xonsh script, as well as capture output of commands - No need to import os, shutil, subprocess, etc. Been using it for a number of years. Really happy with it.
- partdavid 5y ago> Powershell has mv and cp but they don't work the same way or have the same flags. The better idea would not be to try running bash scripts in it, that won't work. The idea would be to use Powershell for your scripts on all three platforms, where Move-Item and Copy-Item do work the same. In Powershell 'mv' and 'cp' are aliases to Powershell commands, which is why they behave differently. As a Unix Powershell user, I don't want or like that, so I remove them. Scripts can always spell things the canonical way and so be guaranteed of the correct behavior. There's a huge caveat to this, but it's no less true for Python or any other language, and that is that lots of platform differences are semantic and not addressable by any shell. In my experience you run into these "other factors" pretty quick, but in the domain of build scripts, they might not matter much.
- chasil 5y agoThis has already been done in ADA. It was designed for better performance than the Cygwin shell. https://archive.fosdem.org/2019/schedule/event/ada_shell/ https://archive.fosdem.org/2019/schedule/event/ada_shell/ https://github.com/AdaCore/gsh https://github.com/AdaCore/gsh You could also use the busybox port of the Almquist shell, if you can refrain from most bashisms. https://frippery.org/busybox/ https://frippery.org/busybox/