Bash libraries as a repo for your most awesome code
Code Hunter
Posted on January 30, 2024
If you are doing something long enough you build up a cool library of code snippets that you want to reuse in your projects over and over again. For bash coders this is no different. I write A LOT of networking related bash scripts (like really a lot). In these scripts many things repeat over and over again, like: What is the IP subnet?, what is my gateway?, what is my Internet exit IP? They are all one line of code, but here is the rub: The more advanced the networking scripts get, the more ninja the forces become to break your one-liners. So a simple:
curl ifconfig.me
grows into a bash function that deals with things like /etc/resolv.conf being eaten 'by some mysterious force', or 'ifconfig.me' being down. More likely than ifconfig.me being down, is some cloud AI thinking you are neferious. No problem we just ask 'ipinfo.io/ip' or 'https://ident.me/'. The Internet being what it is, lets place curl inside a firejail to pro-actively mitigate any future exploits (again) of curl. Now your one-liner has grown into:
${FIREJAIL} --profile=/usr/local/etc/firejail/curl.profile \
--net=${NIC} --dns=${FULL_GW} --defaultgw=${FULL_GW} \
${CURL} -m 2 ${PUBLIC_IP_LOOKUP[${X}]}
This way a simple ping becomes:
#=== Check if GW router is up ------------------------
${FIREJAIL} --profile=/usr/local/etc/firejail/ping.profile \
--net=${NIC} --defaultgw=${FULL_GW} ${FJ_NET_ARGS} \
${PING} -c 1 -W 1 ${DNS_IP} > /dev/null 2>&1
if [[ $? -eq 1 ]]; then return 1; fi
As you can see things grow and grow. In one script I learn one thing, in another bash script project I learn something else like: 'Wow things can get really screwy'. So my ninja code gets more ninja. I move on to other things and months later I remember that I had this cool code but cant remember all the details but I know I WANT that code in this project.
Believe me when I say: copy-and-pasting of this code is NOT a good idea! Why? All the time you learn something new, adjust the code, change it some more and all that you remember is that you have this awesome code snippet that deals with 'X'. The way to keep your future self happy it to place all your battle hardened code into a library that you can link to from all your scripts. So when you update your code in your library, ALL your scripts will benefit from it instantly!
Now for my secret sauce🔥😝 to do this well:
#=== Load my battle hardened code library ------------------
CFG_DIR="${HOME}/mycode/libs/"
LOAD_LIB=0
. ${CFG_DIR}/networking.lib
if [[ ${LOAD_LIB} -ne 1 ]]; then \
echo 'Abort: Missing Library'; exit 9; fi
Before I explain how it works, you HAVE to add the following line to the END of your library file
LOAD_LIB=1
#===[EOF]===
So it works like this:
CFG_DIR
is just a variable with the path to your bash library files. ${CFG_DIR}/networking.lib
this is the bash command for loading/including your additional source code. In this case your networking library. Nothing too special. The magic happens next.LOAD_LIB=0
this is key. You set the value to -say-0
and you added LOAD_LIB=1 to the end of your library file, so when bash loads you library file, it parses all the lines. Right at the end it comes acrossLOAD_LIB=1
and set the value to 1. It will never reach to that line if there is an error within the library file. We use this for the next stepif [[ ${LOAD_LIB} -ne 1 ]]; then
So if all goes well, bash has loaded and parsed all lines and update the LOAD_LIB variable. All we have to do now is to test for it, LOAD_LIB being1
. If not, abort, abort, abort.Now all the functions in your library are available to your script. You can free your mind from many details and focus on your new code. You only have to remember the simple call from your script
WhatIsMyIP
. You can forget about all the hard work to make this happen. Your function is there for you, dealing with all the real world obstacles to get to the answer. You can count on it that it will deliver. It is a gift from your past-self to your current-self. With the library you are creating this awesome team of you, your past-self and your future-self. Your past-self has your current-self covered and both of you are working on gifts for your future-self. Coding is VERY rewarding.
Some words on bash and why I love it so much. Bash has no ego. Bash is glue, glueing compiled code together into something bigger. Bash is really a very simple programming language but it requires skill to appreciate this simplicity. Bash is easy and terse at the same time. When you start to appreciate its simplicity, you reach that guru level that will keep your future-self always happy. It is not uncommon for me come across my own bash scripts that have been in production for 10 or even 15 years, still doing their thing as fresh as on the first day. This why I love Linux and (Free)BSD so much. It allows you to build a legacy that Windows always steals away from you.
From more articles from the trenches, drop me some comments. Thx
Posted on January 30, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.