Error-Free.

That concept is always important.

We should strive for 100% accuracy in all that we do, but in business (as in all things) competing interests arise that must be balanced against this goal. But in the economy that is now developing out of recent world events, it is IMHO, “Error Free” that will help your business stand out from the competitors when customers view our services as “commodities” for the most part (yes, much of IT has become a “commodity” service.)

So, as business slows and our capacity increases due to decreased demand for our commodities, we are faced with a choice (assuming that our “capacity” is the same; that we haven’t decreased it through layoffs) between allowing ourselves to waste that extra capacity on nothing, or devoting it towards improving our product. Assuming we chose to improve our product as a method to differentiate ourselves from the other “commodity” producers, I suggest that “Error Free” (as it should already be a stated goal) might be the easiest improvement to implement.

Now, how can you implement this idea of “Error Free” in production?

#bashscripting nugget:

When testing for a value (in this case, whether an argument was attached to a call for a script) one *could* use an if/then/else statement.

Or, one can be creative with logical operators:

[[ $1 ]] && varInstance=$1 || read -p “`echo -e ‘\nNothing Entered!\nPlease Enter an Instance: ‘`” varInstance 

When using compound logical operators, they are evaluated in order of precedence. In this particular case, from left to right. So, we evaluate whether $1 and whether setting varInstance equal to $1 are true, if either returns false, we resort to the ‘or’ and read the input.

We could, for the sake of clarity (or if combining many operators) have grouped our first compound logical test like this (which is the *better* practice): 

{ [[ $1 ]] && varInstance=$1; } || { our next statement; } 

For more on logical operators and precedence, see: https://lnkd.in/gvAM5sH

#bashscripting nugget:

When we have multiple network interfaces, how do we quickly determine (1) what interface we are using to reach the internet (or that network), (2) what the IP address is for that interface, and (3) what our subnet masking is, using the fewest lines of code possible?

Well, the problem starts in determining how we are reaching the internet (or any specific network).

Yes, we could assume the device is using the default set on our route, but assumptions quickly lead to problems.

We can, instead of assuming, test to see exactly which interface the traffic bound for a specific destination is taking:

nicAddress=$( ip route get $(getent ahosts “8.8.8.8” | awk ‘{print $1; exit}’) | \ grep -Po ‘(?<=(dev )).*(?= src| proto)’ )

Once we have determined which interface we are using to access that network, we will then pull our IP and netmask.

tempIP=$(ip address | grep $nicAddress | tail -1 | cut -d ‘ ‘ -f 6 | sed ‘s/\// /’) ipAddress=$(echo $tempIP | cut -d ‘ ‘ -f 1) whackMask=$(echo $tempIP | cut -d ‘ ‘ -f 2)

And, now we can print it out in a pretty format:

printf ‘%s %s\n’ ‘We are reaching the internet via interface’ $nicAddress ‘using network IP ‘ $ipAddress ‘and /’$whackMask’ masking.’

So, what if you need to determine EXACTLY which sort of Raspberry Pi you are working with?

Perhaps you are running an ansible playbook that is making a network map in order to document which devices are located where. Of course, there are many ways to accomplish this, but I like simplicity and this script gets the job done for me (though I might gather a bit more data than this particular script outputs). Yes, it’s possible to do this locally with an ansible gather facts, but I haven’t gotten around to that part yet (I’m currently working on another issue and, since time is a valuable commodity, I chose this path.) As with everything, I’m always open to suggestions for improvement.

Here’s a little bash script and data file that ansible (or what have you) can push to the device that will output specifically defined output data (see code snippet).

You can find the script and the data file on my github open repository:

RasPi_Hardware_Mod_Rev_codes.sh REQUIRES: RasPi_Hardware_Mod_Rev_codes.data

#BashNugget

dataFile='RasPi_Hardware_Mod_Rev_codes.data'
	
revString=`grep $( cat /proc/cpuinfo | grep Revision | awk '{ print $3 }' | tr "[a-z]" "[A-Z]" ) "$dataFile"`
	
[[ ! $revString = '' ]] && echo 'RasPi Type Found: ' || { echo 'RasPi Type not found: EXITING' && exit; }
	
raspiType=`echo "$revString" | cut -d ':' -f1`
raspiMem=`echo "$revString" | cut -d ':' -f2`
	
echo 'RasPi Type: '$raspiType
echo 'RasPi Mem: '$raspiMem