This trope comes up every time bash is mentioned, without fail. Unless your team enjoys reading this, then no, a general purpose programming language is not a good replacement for what is effectively a "subprocess orchestration language":
from subprocess import run, PIPE
home = os.getenv("HOME")
try:
os.chdir(f"{home}/dev")
except FileNotFoundError:
sys.exit(1)
out = run(("git ls-remote https://github.com/%(repo)s refs/tags/%(tag)s"
% {"repo": shlex.quote("myorg/myrepo"), "tag": shlex.quote("v1.2.3+deadbeef")}).split(" "),
stdout=PIPE, stderr=PIPE)
The line noise is outrageous as compared to a language built for changing directories and running commands
That's not even getting into the pty portion, where the progress of the output isn't visible until the end of it, which is terrible DX
Nice rube goldberg machine. Apart from imports, that is equivalent to
repo = "myorg/myrepo"
tag = "v1.2.3+deadbeef"
out = check_output(["git", "ls-remote", f"https://github.com/{repo}", f"refs/tags/{tag}"], cwd=os.path.expanduser("~/dev"), stderr=PIPE)
Converting exceptions to exits is an anti-pattern that hides the source of the error, f-strings has been a thing for 10 years and argument quoting happens automatically. Progress of output isn't visible in bash either when you capture output with $(), unless you "tee", which opens up another can of "pipefail"-worms.
IMO, using something like Python or JavaScript is a good idea if any of the following criteria is met:
- Working with data more than executing other binaries
- Dominant data processing path is structured (e.g. JSON, XML, binary)
- Script requires complex flow control to be manageable (e.g. functions, if, case)
- Shell UI requirements that involve handling command-line options
- You find yourself going _deep_ into the docs for jq to get the job done
.
Conversely, BASH is better under the following circumstances:
- Orchestrating other binaries the majority of the time
- Simple jobs that work with newline-separated text lines, or all data can be comfortably "stringly typed"
- Launching and job control for other processes
- You just need to glue some other shell commands and binaries together
- Are just manipulating shell environment vars, or providing a custom user shell (e.g. Python venv `activate`)
- Need to wrap a CLI tool in a simple way
.
The minute you have to reach for BASH arrays, case statements, math... stop everything and seriously consider using a language that has stronger support for all that.
Since you’re the only other person in this thread to mention it, I’m surprised the industry has been sleeping so hard on QuickJS as a scripting language runtime.
I think the lack of batteries-included stdlib is probably the biggest holdup, but JS can be much nicer than python for anything that can be decomposed into map/reduce/filter string munging.
I agree. For me, the major stumbling block is what interpreters ship with your typical Linux distro. Python and BASH are usually just... there. Everything else just takes more steps.
yes. I think if you find yourself dropping to sed/grep/awk/find too much, switch to python.
The language itself imho seems more readable. Strings, lists and hashes seem better especially when you choke on quoting.
And the python standard library makes a huge difference when you grow above "simple". I love argparse for readable arguments with help. os.path lets you manipulate paths and filenames in a readable and robust way. you can read and write json, csv and more. datetime lets you manipulate dates and times.
This trope comes up every time bash is mentioned, without fail. Unless your team enjoys reading this, then no, a general purpose programming language is not a good replacement for what is effectively a "subprocess orchestration language":
The line noise is outrageous as compared to a language built for changing directories and running commandsThat's not even getting into the pty portion, where the progress of the output isn't visible until the end of it, which is terrible DX
Nice rube goldberg machine. Apart from imports, that is equivalent to
Converting exceptions to exits is an anti-pattern that hides the source of the error, f-strings has been a thing for 10 years and argument quoting happens automatically. Progress of output isn't visible in bash either when you capture output with $(), unless you "tee", which opens up another can of "pipefail"-worms.This falls under the case “unless the bash script is simple “.
If you consider more complex tasks, bash quickly gets unwieldy, and the situation is reversed.
Pythons has a lot of advantages, including full flexibility, error handling etc.
In xonsh[0], that would be:
(Not sure about the equivalent of shlex.quote, but in the worst case, you can just use "from shlex import quote as q" or something).So yes, there are good alternatives to bash - even Python based.
[0] https://xon.sh/
IMO, using something like Python or JavaScript is a good idea if any of the following criteria is met:
- Working with data more than executing other binaries
- Dominant data processing path is structured (e.g. JSON, XML, binary)
- Script requires complex flow control to be manageable (e.g. functions, if, case)
- Shell UI requirements that involve handling command-line options
- You find yourself going _deep_ into the docs for jq to get the job done
.
Conversely, BASH is better under the following circumstances:
- Orchestrating other binaries the majority of the time
- Simple jobs that work with newline-separated text lines, or all data can be comfortably "stringly typed"
- Launching and job control for other processes
- You just need to glue some other shell commands and binaries together
- Are just manipulating shell environment vars, or providing a custom user shell (e.g. Python venv `activate`)
- Need to wrap a CLI tool in a simple way
.
The minute you have to reach for BASH arrays, case statements, math... stop everything and seriously consider using a language that has stronger support for all that.
Since you’re the only other person in this thread to mention it, I’m surprised the industry has been sleeping so hard on QuickJS as a scripting language runtime.
I think the lack of batteries-included stdlib is probably the biggest holdup, but JS can be much nicer than python for anything that can be decomposed into map/reduce/filter string munging.
I agree. For me, the major stumbling block is what interpreters ship with your typical Linux distro. Python and BASH are usually just... there. Everything else just takes more steps.
don't listen to the others.
yes. I think if you find yourself dropping to sed/grep/awk/find too much, switch to python.
The language itself imho seems more readable. Strings, lists and hashes seem better especially when you choke on quoting.
And the python standard library makes a huge difference when you grow above "simple". I love argparse for readable arguments with help. os.path lets you manipulate paths and filenames in a readable and robust way. you can read and write json, csv and more. datetime lets you manipulate dates and times.
yes, unless you need it to run somewhere that you know only has bash.