8

I've written a bash script, which process multiple files. I now want to add support for a config file. This is my wanted data structure:

Array ( 
    [0] => Array (
        [name] => datset1
        [path] => /var/lib/bliTool/ds1
        [type] => cvs
    )

    [1] => Array (
        [name] => datset2
        [path] => /var/lib/bliTool/ds2
        [type] => xml
    )

    [2] => Array (
        [name] => datset3
        [path] => /home/igor/test/ds3
        [type] => cvs
    )
)

Q1 Is such a data structure possible within bash? Are there other recommendations? Remember, this should be in a config file...

Q2: I am thinking about one configuration file per 'set' like

/etc/myApp/
/etc/myApp/myApp.conf
/etc/myApp/datasets.d/
/etc/myApp/datasets.d/ds1.conf
/etc/myApp/datasets.d/ds2.conf
/etc/myApp/datasets.d/dsN.conf

and each /etc/myApp/datasets.d/dsN.conf file would look like

name=The DS name
path=/the/path/to/the/ds/files
type=thetype

What do you recommend? Is there a way to do everything in one file?

Q3: I want to support multiple path values per set. I could support something like

path="/first/path /second/path"

But I think I'll get trouble with spaces, so I should introduce a delimeter like

path="/first/path:/second/path"

to split the string.

Or is there a better way?

4
  • You mean like tldp.org/LDP/abs/html/arrays.html ? Commented Mar 28, 2013 at 14:38
  • Yeah, something like that. Can I mix indexed arrays with assoc arrays in bash? And will it be suitable for a configuration file? Commented Mar 28, 2013 at 14:41
  • Have you considered using Perl instead? Commented Mar 28, 2013 at 14:50
  • It's possible, in the sense that bash is Turing-complete. You probably don't want to write or maintain the code required to do so, however. Commented Mar 28, 2013 at 15:04

2 Answers 2

15

You can't nest data strutures in bash. At best, you can store the names of associative arrays in an array, and jump through indirection hoops to access them.

$ declare -A aa0=([name]=dataset1 [path]=/var/lib/bliTool/ds1 [type]=cvs )
$ declare -A aa1=([name]=dataset2 [path]=/var/lib/bliTool/ds2 [type]=xml )
$ declare -A aa2=([name]=dataset3 [path]=/home/igor/test/ds3 [type]=cvs )

$ declare -a array=( aa0 aa1 aa2 )
$ tmp=aa0[name]
$ echo ${!tmp}
dataset1  

For the second question, it's certainly possible to define a configuration file format with sections, but you'll need to write a parser that can process it. Other languages typically have a library available to parse rich configuration file formats.

As far as multiple paths per variable, stick with :. In theory, any delimiter could be used as part of a path name component, and so the delimiter needs to be quoted if it is part of a path. But since PATH uses : as its delimiter, there is historical awareness that : is not a great character to use in a path name, and that it needs to be quoted in PATH-like parameters.

path="/first/poor\:path\:name:/second/bad\:path\:name"

Then it will be up to your application to process the back-slashed :.

Sign up to request clarification or add additional context in comments.

2 Comments

I found this example very helpful but one question: how to iterate over the array named 'array' and then, for each element, access the 'name', 'path' and 'type' values?
That's a good question, but it would be better posed as a separate question (which can reference this answer) rather than in a comment.
1

I came into a similar situation and my solution is to use different IFS within different level, it is somehow similar to chepner's idea. The code and sample can be found here https://github.com/pppoe/Nested-Array-Bash/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.