why?
Because bash feels clunky to write and work with for anything non-trivial, especially compared to other scripting languages.
Why not another scripting language (no compile necessary)?
Because bash and sh are installed nearly everywhere. Any other scripting language means the user is required to have that installed, and that is far less likely to be the case.
If I could write my scripts in a nice syntax, but be sure my users will be able to use it effortlessly by distributing to them compiled versions, then that would make both of our lives easier!
Thoughts? Are there any languges that do this?
Unfortunately shell script is not as portable as you might be anticipating. Different distro run different shells, with different settings, and also different tools. Think BSD grep vs GNU grep.
I discovered a fun one the other day: there is literally no way to represent word-boundary anchors that’s valid in both GNU
sed
and BSDsed
. https://unix.stackexchange.com/a/393968/38050I’ve seen multi distro scripts that are also able to bootstrap their own assets for each distro/architecture. Don’t see why you wouldn’t be able to check that considering
/etc/os-release
exists in pretty much every unix like environment.And having it run on a specific shell type could also be an option.
That’s what the POSIX spec is for. BSD and GNU commands may differ, but they both support what’s specified by POSIX. By limiting your calls to it, you can write portable script with no problem (I’ve been doing that for the last few years without issue).
Giga brain move: make a bash script that compiles some c code then runs it
Still requires the compiler though.
I don’t have a good answer, but I’ve embedded python in bash scripts before after having the bash script install python. Take that as you will.
I use this nice trick to use Clojure has a bash script. This auto-download clojure so this id quite portable and reproductible.
Previously I also used Haskell’s turtle lib that could run with a portable shebang and it could even be compiled later if you need more speed.
I’m gonna pile in with yet another option that isn’t a language that compiles to bash…
Consider Ruby for easier shell scripting. With its back tick syntax for executing shell commands, it’s quick to use when you want to glue together a series of commands. …and then you get to use a sane syntax for your script’s logic.
Ex:
# Check my history for all usages of the xsv command # and extract the filename csv_files = `grep ~/.zsh_history "xsv" | awk '{print $3}'`. split("\n"). map(&:chomp) # list any csv with my phone number csv_files.select { | filename| `grep #{filename} "555-1234"`.chomp != "" }.each {|filename| puts filename}
Why not another scripting language (no compile necessary)? (…) If I could write my scripts in a nice syntax, but be sure my users will be able to use it effortlessly by distributing to them compiled versions, then that would make both of our lives easier!
Would it make sense to describe your idea as a typescript for bash or sh?
There’s always Golang which compiles to an x86 binary. But that’s probably not what you want since you probably want something readable and editable on the end system.
Not exactly what you asked for, but take a look at Nushell
I’m familiar with NuShell and looks very nice. But unfortunately yeah, not what I’m looking for. It would require installation by user.
Install nushell vie bash and then pipe your commands into it?
op asked about using bash because it’s already there. Your answer is the complete opposite of that. twice
Doesn’t powershell do this? I’ve been learning powershell, and they keep making a tech agnostic claim along these lines, but I haven’t tested it on Linux yet.
Powershell exists for Linux, that’s probably what they’re talking about. Since Poweshell has objects and shell commands typically dump out text which then needs to be parsed with regex or something, I don’t anticipate there would be an easy conversation tool.
Not quite - even in PowerShell 7 there are some features that only work on Windows and Windows only comes with PowerShell 5.1 by default.
I used it on a Mac and on Windows, for me it feels very modern when compared to bash (although I never was a bash expert).
However, the problem is that it’s not installed by default on Linux (at least on most distros as far as I know) and Mac, and Windows machines might have an outdated version which you’ll have to take into account.
So unfortunately it doesn’t meet OP’s criteria that it should “just work” without installing an interpreter.
Just use Python. If you absolutely need it on every system use go and compile it down to a binary.
Hate this because most bootstrapping I do is within a
Dockerfile
where I don’t want to install the entire runtime and its dependencies just to complete a build step.
python is usually the next step up in admin land
python is a pretty standard install on linux systems since so many things like you’re talking about use it
Not only that it’s basically everywhere, but even if it’s not, you can compile it using something like nuitka and still use it.
Huh, why doesn’t python just ship this? Managing python installs is annoying as hell.
I would guess mostly because python interpretes are just about everywhere.
Also the binaries compiled with nuitka end up being much bigger in size. A simple script of a few kb can and up in the hundreds of mb when you start compiling the dependencies, so it’s not a perfect solution.
This is about python packaging, like making/getting libraries/apps rather than compiling binaries, but it’s pretty relevant here:
https://chriswarrick.com/blog/2023/01/15/how-to-improve-python-packaging/
Python or Perl. IIRC, I’ve seen systems with a Perl install by default, but not Python.
Although it doesn’t crosspile to bash, I think a good middle ground is bitfield/script. Basically you can do many things you would normally script very simply with nice syntax and distribute a binary.
https://github.com/tdenniston/bish is one such language.
I’d also recommend Shellcheck which helps prevent many problems with shell scripts.
The way I used to solve this problem back in the day was with a statically compiled Perl binary.
Why not another scripting language (no compile necessary)?
But you’re describing compiling that new language to bash…
Is transpiling a form of compiling?
Yes, that’s where it’s name comes from!
Yes, I’m answering why I am not taking a completely other scripting language
In other words, I am making the case for a compiled language by answering the question of why i am not considering a language that doesn’t need it.
Why not use a compiled language that compiles to fat binaries (rust, go etc)?
It’s worth noting any compiled language can make a “fat” binary (e.g., C++), you just need to use static linking.