I am planning a script to manage some pieces of my Linux systems and am at the point of deciding if I want to use bash or python.
I would prefer to do this as a Bash script simply because the commands are easier, but the real deciding factor is configuration. I need to be able to store a multi-dimensional array in the configuration file to tell the script what to do with itself. Storing simple key=value pairs in config files is easy enough with bash, but the only way I can think of to do a multi-dimensional array is a two layer parsing engine, something like
array=&d1|v1;v2;v3&d2|v1;v2;v3
but the marshall/unmarshall code could get to be a bear and its far from user friendly for the next poor sap that has to administer this. If i can't do this easily in bash i will simply write the configs to an xml file and write the script in python.
Is there an easy way to do this in bash?
thanks everyone.
Bash does not supports multidimensional array, but we can implement using Associate array. Here the indexes are the key to retrieve the value. Associate array is available in
bash
version 4.I am posting the following because it is a very simple and clear way to mimic (at least to some extent) the behavior of a two-dimensional array in Bash. It uses a here-file (see the Bash manual) and
read
(a Bash builtin command):Output:
Physicist Wolfgang Pauli was born in 1900 Physicist Werner Heisenberg was born in 1901 Physicist Albert Einstein was born in 1879 Physicist Niels Bohr was born in 1885
The way it works:
read
command in the Bash manual) separate the elements of these vectors.read
command with its-a
option, we loop over each line of the file (until we reach end of file). For each line, we can assign the desired fields (= words) to an array, which we declared just before the loop. The-r
option to theread
command prevents backslashes from acting as escape characters, in case we typed backslashes in the here-documentphysicists.$$
.In conclusion a file is created as a 2D-array, and its elements are extracted using a loop over each line, and using the ability of the
read
command to assign words to the elements of an (indexed) array.Slight improvement:
In the above code, the file
physicists.$$
is given as input to thewhile
loop, so that it is in fact passed to theread
command. However, I found that this causes problems when I have another command asking for input inside thewhile
loop. For example, theselect
command waits for standard input, and if placed inside thewhile
loop, it will take input fromphysicists.$$
, instead of prompting in the command-line for user input. To correct this, I use the-u
option ofread
, which allows to read from a file descriptor. We only have to create a file descriptor (with theexec
command) corresponding tophysicists.$$
and to give it to the-u
option of read, as in the following code:Notice that the file descriptor is closed at the end.
Independent of the shell being used (sh, ksh, bash, ...) the following approach works pretty well for n-dimensional arrays (the sample covers a 2-dimensional array).
In the sample the line-separator (1st dimension) is the space character. For introducing a field separator (2nd dimension) the standard unix tool
tr
is used. Additional separators for additional dimensions can be used in the same way.Of course the performance of this approach is not very well, but if performance is not a criteria this approach is quite generic and can solve many problems:
The output of that sample looks like this:
I've got a pretty simple yet smart workaround: Just define the array with variables in its name. For example:
Don't know whether this helps since it's not exactly what you asked for, but it works for me. (The same could be achieved just with variables without the array)
This is what worked for me.
It's based off of this answer here