I have wondered if there could be a CoffeeScript or TypeScript of Bash. Basically a transpiler to Bash that is safer and more convenient to write in.
Then you just ship the bash script with no dependencies. The transpiler might even be smart enough to take GNU/BSD differences into account.... ahh another project idea that I do not have time to implement :(
EDIT: Apparently there is one and it is even the language I would have problem implemented the compiler in (OCaml) [1] . It is shame though it doesn't seem to have much functionality other than checking if files exist and string manipulation. If they had just focused exclusively on Bash/coreutils (and Powershell for windows) they could probably add a lot more features.... Windows seems to be holding them back.
There is also m4sh which are just M4 macros that compile to portable bash scripts. Albeit it is not convenient to write in, and probably harder to avoid making mistakes.
If you need something this elaborate, you really shouldn't be writing it in Bash in the first place.
Anytime I find myself wishing I had arrays, or real data types, or real functions, I stop using shell languages immediately. Shell scripts are really only suitable for the exact same sorts of things I would type myself at a Unix prompt...and since those sorts of things are rarely more than a few lines long, shell scripts shouldn't be longer than that either.
I can think of some cases where it might make sense depending on the specific details. For example if you already had tons of scripts that you wanted to wrap and one couldn't install things as root this could be the quickest path forward.
The nice thing about shell languages (like sh and to some extent bash) is they run everywhere with minimum dependancies. This makes them great for things like build environment configuration. Those scripts can easily get very complex and it's nice to have some built-in tools to help keep it under control.
Cool idea. Wish it supported Bash 3 (did read the note on that). For some strange reason, sourcing Lib/Array/Intersect.sh is an infinite loop. The full library, apart from that file, sources in a few seconds which isn't terrible:
$ time { . lib/oo-bootstrap.sh ; for f in `find lib/ -type f -name '*.sh' -not -name oo-bootstrap.sh` ; do echo $f && source $f ; done ; }
lib/Array/Contains.sh
lib/Array/List.sh
lib/Array/Reverse.sh
lib/String/GetSpaces.sh
lib/String/IsNumber.sh
lib/String/SanitizeForVariable.sh
lib/String/SlashReplacement.sh
lib/String/UUID.sh
lib/TypePrimitives/array.sh
lib/TypePrimitives/boolean.sh
lib/TypePrimitives/integer.sh
lib/TypePrimitives/map.sh
lib/TypePrimitives/string.sh
lib/UI/Color.sh
lib/UI/Console.sh
lib/UI/Cursor.sh
lib/util/bash4.sh
lib/util/class.sh
lib/util/command.sh
lib/util/exception.sh
lib/util/log.sh
lib/util/namedParameters.sh
lib/util/pipe.sh
lib/util/test.sh
lib/util/tryCatch.sh
lib/util/type.sh
lib/util/variable.sh
real 0m2.490s
user 0m1.240s
sys 0m0.834s
Sadly it broke my already installed bash completion:
$ ls # + <TAB>
x UNCAUGHT EXCEPTION: quoted
gsed: -e expression #1, char 2: invalid usage of line address 0
|} [bash_completion:0]
|} * _filedir [bash_completion:1196]
|} x COMPREPLY=( $( compgen -P "$prefix" -W "${COMPREPLY[@]}" ) ) [bash_completion:1196]
! Press [CTRL+C] to exit or [Return] to continue execution.
I don't understand why somebody would use Bash in this way though, maybe just for fun?
It is odd. It's not like you can assume bash is everywhere, it's not installed by default on some BSDs (unless this is really an sh standard lib, not bash). You're probably better off going with Perl, it probably exists on the system you are targeting (and it's quite heavy, but it you want to you can package it into an executable for Windows if you need).
Do you know if anyone has done a survey of what software is on almost all the BSD or Linux boxes for deployment purposes? Especially, transpiling unsupported X to supported Y.
No, but that would be wonderful! A caniuse.com for operating systems, listing whether a major for of software (library, interpreter, compiler, shell) is available as part of the default install, part of additional packages from the core set during install, from additional packages blessed by the provider but not available through install media, a third party repo, source compilation, or is known to not be functional.
I see bash as a lowest common denominator for ops & sys admins. There would be too much friction getting the pack to agree on python, perl, ruby, etc., especially since most of the code would be shell'ing out commands to /bin/sh or /bin/bash anyway.
Bash does leave a lot to be desired when it comes to data structures and error handling, but in some cases it makes the most sense. In those cases, better to have some semblance of sanity via a common lib like bash-infinity or bash-booster.
Although after looking at it some more, it bears little semblance to bash - kills my "common denominator" argument. I prefer a more bash-booster approach: bash plus common functions to standardize on.
I think it is unlikely somebody would use Bash Infinity interactively, since it's apparently targeting scripting:
"The aim of Bash Infinity is to maximize readability of bash scripts, minimize the amount of code repeat and create a central repository for well-written, and a well-tested standard library for bash."
This is a really interesting project for testing the boundaries between "shell scripting", "scripting" and "programming".
The semantics are advanced enough and different enough, that if I needed them, I would probably write the code in my favorite "scripting" language such as Python or NodeJS.
If Bash Infinity became ubiquitous, would it displace that "scripting" sweet spot that has been pretty constant with Perl/Python/Ruby for two decades? Or are you better of with a dedicated scripting language?
Of course you can write "shell scripts" in Haskell (or insert your favorite lang), but the tooling and rigor pushes you into "programming" territory.
I often feel Bash is too limited, and the language really could be extended. For instance passing anything by reference is a huge pain to deal with (using global variables is a very ugly workaround).
Then you just ship the bash script with no dependencies. The transpiler might even be smart enough to take GNU/BSD differences into account.... ahh another project idea that I do not have time to implement :(
EDIT: Apparently there is one and it is even the language I would have problem implemented the compiler in (OCaml) [1] . It is shame though it doesn't seem to have much functionality other than checking if files exist and string manipulation. If they had just focused exclusively on Bash/coreutils (and Powershell for windows) they could probably add a lot more features.... Windows seems to be holding them back.
[1]: https://github.com/BYVoid/Batsh