One of the many things that I love about coding/scripting is that there are numerous solutions for the same problem. Whether that is using a different command to achieve the desired effect or for example using different loop formats (bash
allows you to use C syntax for loops as well!).
I’ve been working on another script lately that has taken up some considerable amount of time. I am referencing a number of scripts to achieve my results, however I’ve either tried to simplify, improve or just make my version function better. Another aim is for it to be used by those with very little scripting knowledge and in limited amount of time tailor it to their own needs.
A big source of help has been reading Defensive BASH Programming by Kfir Lavi. I’ve been able to implement a number of elements from that article in my scripting and I believe it has meant that my scripts are improving.
Most of the easier and straight forward functions of the script have been completed. Some of the script has been tested and it’s working well, other parts I’ve just been tinkering away on and feel that it will probably be tested in a live environment when it is done and I will iron out the kinks.
Since the other day I’ve been trying to figure out the following line from the code:
read PART TYPE SIZE USED PRIO <<< $(swapon -s 2> /dev/null | tail -n 1 2>/dev/null) 2>/dev/null if [ "${TYPE} != "partition" ]; then print_FAIL echo "Swap is not a partiton." fi if ! (( 256000 < ${SIZE} && ${SIZE} < 300000 )); then print_FAIL echo "Swap is not the correct size" fi
Something similar was done to checking Logical Volumes/Virtual Groups and such. I knew read
was a built in command within the bash shell
that was used to take input from stdin
, however I was not 100% sure how it was being utilized in this case.
A bit of research lead me to this article, which covered extensively how the read
command actually works. I learnt from the article that the command actually assigns a value to each word, usually treating a word when white space is detected (although this can be changed using the -d delim option, which provides a new delimiter).
After some trial and error, I was able to play around with it and replicate what the script was doing. To a certain degree I felt other options were also available, as the previous day I resolved an issue of using awk
to accomplish a similar result without requiring read
.
Below is an example of achieving the same result, using a variety of methods. I know one is purely replacing the command with a variable, but it just shows that the same result can be completed. Here are a few examples of this – and I’m sure others could come up with a number of other solutions:
#!/bin/bash function swap_variable_loop() { printf "Testing SWAP with variable loop:\n" local readswap=$(swapon --noheadings) echo $readswap | while read NAME TYPE SIZE USED PRIO do echo "NAME: $NAME" echo "TYPE: $TYPE" echo "SIZE: $SIZE" echo "USED: $USED" echo "PRIO: $PRIO" # printf "${wordarray[@]}\n" done } function swap_loop() { printf "Testing SWAP with loop:\n" swapon --noheadings | while read NAME TYPE SIZE USED PRIO do echo "NAME: $NAME" echo "TYPE: $TYPE" echo "SIZE: $SIZE" echo "USED: $USED" echo "PRIO: $PRIO" done } function swap_loop_array() { printf "Testing SWAP with loop and array:\n" swapon --noheadings | while read -a swaparray do local n=0 for i in NAME TYPE SIZE USED PRIO do echo $i":" ${swaparray[$n]} n=`expr $n + 1` done done } function swap_awk() { printf "Testing SWAP with awk:\n" echo -n "NAME: " && swapon --noheadings | awk '{ print $1 }' echo -n "TYPE: " && swapon --noheadings | awk '{ print $2 }' echo -n "SIZE: " && swapon --noheadings | awk '{ print $3 }' echo -n "USED: " && swapon --noheadings | awk '{ print $4 }' echo -n "PRIO: " && swapon --noheadings | awk '{ print $5 }' } swap_variable_loop swap_loop swap_loop_array swap_awk
And for the results:
Testing SWAP with variable loop: NAME: /dev/dm-1 TYPE: partition SIZE: 980M USED: 580.8M PRIO: -2 Testing SWAP with loop: NAME: /dev/dm-1 TYPE: partition SIZE: 980M USED: 580.8M PRIO: -2 Testing SWAP with loop and array: NAME: /dev/dm-1 TYPE: partition SIZE: 980M USED: 580.8M PRIO: -2 Testing SWAP with awk: NAME: /dev/dm-1 TYPE: partition SIZE: 980M USED: 580.8M PRIO: -2
With the above scripts, I have options to play with, whether I assign the result of the swapon
command using read
or I use awk
to just grab the relevant bits to use in the function. Hope this article has been useful in better understanding how you can approach a problem from multiple angles and methods along with better understanding a few commands!