Remember that time bumblebee accidentally deleted everyone's /usr? Or that time steam deleted everyone's homedir? Both because of the easiest to avoid bash footguns - spaces and empty variables.
My hard and fast rule that I've never regretted is - if you use a bash if statement, consider python. If you're going to do a for loop, you must instead use python.
Typically as a side effect once the programmer is in python at my prompting, they find having such easy access to libraries suddenly lets them make the whole script more robust - proper argparsing is an immediate one that comes to mind.
Frequently the reticence I see from people, especially juniors, is that they're worried about people thinking "haha they have to pull an entire python into their image just to run this script" or "wow they're so newbie/young that they can't even write some shell". I reassure them: don't worry, there's a reason we used Perl even back then too.
for i in `seq 1 10` ; do
echo i $i
done
for i in range(1,10):
print("i %i\n")
You might find problems with the shell code, and I'll find problems with the Python. But both will print 1 to 10.The biggest reason why I don't use it all of the time is that calling / piping commands takes a lot more typing, so it's easier to use bash for very simple shell scripts. And while there are libraries that simplify shell scripting, that adds external dependencies to your scripts.
> for i in range(1,10): > print("i %i\n")
This outputs "i %i\n\n" 9 times.
damn, ya got me there. to be fair, I was drunk when I wrote that xD
Most of the things on this list couldn't happen in Python:
https://www-uxsup.csx.cam.ac.uk/misc/horror.txt
Your exanples were bugs which were not caught during development because "testing is hard and expensive" and "if it compiles, ship it".
If you want to do more advanced things there is always the right tool for the job although with an increased attack surface.
Using shell script instead of a sane language is like opening beer with your teeth because you can't be bothered to get a bottle opener.
Bash may or may not. It depends on how your script was called. If your script is sourced you need to remember to set and restore the flags.
In bash your data can accidentally become code. "rm $fn" usually deletes one file, but it might one day delete a few (spaces), or wildcard expansion makes it delete many. With Python, calling the function to delete one file will always delete one file. Your function will never run with a "continue on errors" mode.
and it's easy to add status checks to your shell script just like you can for Python. exceptions are not the only way to stop on error. but it's sure a hell of a lot easier to have a non-working program in Python, whereas it's a lot easier for a shell script to keep working.
Bash is also good at these things but it feels like you are using weird archaic tools to get things done. They work very well but the syntax on some of the commands you end up having to use are entire oriley books by themselves. It has its own odd way of doing things. Bash is nice for when you know you can not really manipulate the environment. As it is fully complete and usually 'table stakes' for what is installed. It is just kind of odd the way it works. In this case I decided to start with something that is more akin to what I am used to writing.
There are plenty of cases in which Perl or Python will make things much more complicated than 5 lines of spooky-looking shell script. Sometimes a little mystical sorcery is what the doctor ordered.