Shell Script Dictionary

Shell Script Dictionary

If you are looking for the code directly, please refer to my repo. For the motivation and different use cases where you can use this, please continue reading as you may find it useful.

When working with MacOS or in the *nix world, there is a consistent struggle on how to arrange and manage data in shell scripts in a similar fashion on how you would do in other mature programming languages like Python/Java.

If it is so complex, then why even try writing shell scripts in the first place? The reason, for me at least is not because I have a choice. It is because I do not want to deal with installing dependencies, run times and complex development environments. If I want to check something quick, then a shell script is the way to go!

Example-1: Say I want to automate a complex server configuration using Ansible or Terraform, which involves setting up network interfaces based on the *nix flavor. If I want to use python for this, I need to ensure that my server already has python installed, which is an extra configuration step, which means I cannot use the base OS template directly. A shell script will save the day!

Example-2: You want to monitor a process in a loop and monitor the system loading when you are running your target service or application. A simple shell script snippet using ‘ps’ command will be a life saver. Again, for this task, installing dependencies will be an overkill. The below snippet on the command line directly will help you monitor the a process using its PID at every second.

PID=12345
while true; do ps aux | grep $PID | head -n 1; sleep 1; done

Now, say you want to do some complex stuff, like update multiple network interfaces with preset configs, monitor many processes using their names, create scalable data dumps by monitoring different sysfs nodes at regular intervals, etc. and on and on. To manage that, you will need a dictionary or a hash map type data structure. This is not something that you can achieve in shell using any built-in stuff, so you need to create some hacks to achieve similar functionality in your shell. In this blog, I will go over how I achieved it, and it has been extremely useful for me! I hope its useful to you too.

Create an array with the format of ‘key:value’ for each item.

MAP=( "a:1"      
"b:2"
)

To read the keys from ‘our dictionary’ above (actually an array :-)), loop through each of the array item, and use regular expression to get the keys. Refer: Github repo

keys()
{
INPUT_DICT=("$@")
KEYS=()
for DATA in "${INPUT_DICT[@]}" ; do
KEYS+=("${DATA%%:*}")
done
echo "${KEYS[@]}"
}
echo "KEYS=$(keys "${MAP[@]}")"
# this will give 'a b' i.e. keys from the map

Similarly, to get the values from ‘our dictionary’, use regex to get the element on the right hand side. Refer: Github repo

values()
{
INPUT_DICT=("$@")
VALUES=()
for DATA in "${INPUT_DICT[@]}" ; do
VALUES+=("${DATA##*:}")
done
echo "${VALUES[@]}"
}
echo "VALUES=$(values "${MAP[@]}")"
# this will give '1 2' i.e. keys from the map

Similarly, say you want to pretty print, or access each item in key-value fashion like the python’s dictionary iteritems(), you can do something like below. You can modify this to achieve whatever functionality you wish to achieve.

pprint_dict()
{
INPUT_DICT=("$@")
for DATA in "${INPUT_DICT[@]}" ; do
echo "${DATA%%:*}:${DATA##*:}"
done
}
# this will give 'a:1 b:2' i.e. keys from the map

NOTE: Though this allows to mimic the hashmap or dictionary functionality, it is not exactly the same thing. For example, a dictionary boasts of a constant read time because it allows to store data based on hash of the key. The output of the hash function determines the location of the item in the dictionary. This solution here is more of a workaround then an actual hashmap in shell. It only allows you to have kind of a similar interface, but the access time scales linearly based on the number of elements in the data structure, as you are basically creating an array in a pre-determined format for each element.
To download the sample code, refer to my Github repo.

Look forward to waking up every day to an interesting challenge!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store