Getting Bashed by Dynamic Arrays

Written by on August 24, 2015 in Linux, Technology, Tutorials

The reason most people love Linux is because of the ability to quickly prototype a system; due to the plethora of free software, command line tools, tool kits, and scripting languages available to choose from. Recently I was working on a script written in the Bourne Again SHell commonly known as (bash). The primary reason for choosing Bash was because it’s widely available and it supports arrays and associative arrays; unlike it’s predecessor the Bourne Shell aka (bs) … just kidding it’s actually (sh).

The script would use curl to make web-services calls, xmllint for XML parsing, and some other commonly used Linux tools such as grep. This command line tool would essentially pull XML based software catalogs which contain software versions, upgrade paths, and other content which could be downloaded via the web service. Parsing data via pipes to xmllint, sed, awk, and grep is an easy task, but storing that data into data purely Bash data structures/types presents some interesting challenges. The goal in the end is to dynamically build a software catalog which allows the user to interact with Text User Interface (TUI) to download the needed components for installation later. Everything from the software classes, version names, and upgrade paths is unknown prior to the initial web-service call.

Any well versed programmer by now has thought to themselves, “It’s easy you have arrays and associative arrays how hard could that be?”

Let’s cover the basics around arrays without introducing anything dynamic just dealing with spaces.

Let’s cover the basics around associative arrays without introducing anything dynamic just dealing with spaces.

This means that neither arrays or associative arrays support list assignment at an index or key respectively thus ruling out the following options:

For the most part everything else works as one would expect, but there is no native support for multi-dimensional arrays although there are plenty of ways to simulate this behavior all of which can get quite dirty before even adding dynamic variables. When creating a dialog driven system it is going to be necessary be able to directly map an option index to an array index as shown below:

  1. Microsoft
  2. IBM
  3. Solar
  4. Exit

Please select an option: 1

These options would naturally lead to to other dynamically generated options

Microsoft Software

  1. Microsoft Office
  2. Microsoft Visio
  3. Micorsoft Visual Studio
  4. Back to the previous menu

Please select an option: 1

Microsoft Software

  1. Office 95
  2. Office 98
  3. Office 2005
  4. Office 2011
  5. Back to the previous menu

These options would once again lead to other dynamically populated data which would result in an acquisition. The same is true when using ‘dialog’ to for presentation of menus, checked lists, or radio lists.

dialog –ascii-lines –menu “Choose software vendor:” 20 80 5 1 Microsoft 2 IBM 3 “Sun Microsystems”

dialog_example

 

 

 

 

 

 

 

 

At this point in time it’s probably worth showing some of the options for dynamic variables using ‘declare’

Now that we have seen how to implement this simulated dynamic data type with ‘declare’ we can try to do it without

The next step is to apply what we have learned about dynamic variable creation and apply it to dynamic variable array creation using declare

Now that we have seen how to implement this dynamic variable array with ‘declare’ we can try to do it without

It pretty easy to see that this can get quite complicated once you need to dynamically pass the variable name, index, and value. Especially when you start to consider the limitations of indirect array references using ‘!’ it is not possible to get the number of items stored in the array.  It’s best to encapsulate that in some functions to make life a bit easier. It also allows us to make sure that variables adhere to the proper naming convention. The functions below allow creation, insertion, retrieval, and assignment very easy. It should be noted that you can use ‘declare’ within a function but you will need to pass -ag to make the variable scope global.

This final example uses a Bash 4.3 feature called ‘nameref’ which allows you to reference a variable by the variable name which is much safer than using ‘eval’, however; depending on the system being used Bash 4.3 may not be available.

In conclusion, I hope this will help people get their heads around dynamically named variables and dynamically named arrays in Bash. Although these data structures are well known and simple; trying to implement them to be defined on the fly can be frustrating especially without the added ‘nameref’ capabilities of newer versions of Bash.

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

Subscribe via RSS Feed

Comments are closed.

Top