At my last full-time job, I wrote some hideously complex bash scripts. They started out small and kind of got away from me. In hindsight, that’s pretty much the way it had to be. I was in charge of dozens of linux computers running hundreds of programs that I wrote, interacting with each other in complex ways. I didn’t fully understand the problem space, and even if I had, I didn’t have time to write all that logic in a more formal language. bash scripts are the perfect medium for spitballing solutions to problems you’re kind of fuzzy about.
This was my first attempt to solve big problems with bash, so I had a lot to learn. For example, I was surprised to discover that this script doesn’t work:
This is an attempt to call a function before it’s defined. Trivial in C++, my native language, but not allowed in bash.
I’m kind of embarrassed to admit that I struggled with this for a long time. I wrote more and more bash functions, which became increasingly interdependent, so this problem got more troublesome as time went on.
For this reason and many others, I decided to adopt a more C-like structure for my bash scripts. Like this:
main() is calling test1() and test2() before they are defined. But it doesn’t matter anymore, because all functions are defined before the program starts running. The bash interpreter has read the entire script before execution begins at the very last line, when main() is called.
I would have done this right from the beginning, but I didn’t know about the $* trick. That passes all command-line parameters received by the script to the main() function, so it can do whatever it likes with them.