Currently my main project(s) exist out of one configuration process to build a deployment/production server supporting Docker environments, and I’ve chosen to do it in Bash.. maybe that’s bad, but challenging a lot for me. I have build a structure for it that depends on files that have their own tasks, and different sorts of functionalities to let it behave as a framework kind of deployment. I spent many times on rebuilding it and improving myself as it was my real first project that I wanted to finish at least with intelligence behavior.
But the last couple of days, I thought about a solution for one part that I’m writing;
The task is to make sure that a shortcut collection of directories has been created and filled with Git repository content, and I want to execute the deployment from there. These repositories for this destination are mainly configuration files supporting Docker images or Git hook deployment. However, I work with different kinds of array lists:
DEPLOYMENT_DIRECTORY_ASSIGNMENT=(
"layer_1:layer_2:server-deployment-repository"
"layer_1:layer_2:layer_3:deployment-hooks-repository"
"layer_1:layer_2:layer_3:nginx-configs-repository"
)
Some explanation; the ‘layers_*’ are supposed to be directories, these are going to be
created within the server environment as the format: ‘layer_1/layer_2/layer_3’. My plan
is to use layer_1 as hidden directories what means that they can be equal at most,
layer_2 can be equal as well and will function as a category. However, ‘layer_3’ isn’t
always needed (example is the first value of the array). For the first entry
‘layer_1:layer_2:server-deployment-repository’ I will use it as ‘.hidden/setup’ since I
want to have the ability for being able to (re) launch the deployment from there, and
according to its format, there seems no reason to use a third layer.
The values at the end of the list from left to right are obviously repository names and serve as sources. This is not a directory layer like the rest, but this will be used to find the repository based from a certain path and to serve the functionality of configuring relations between the repository content and layered folders.
This task is currently working on my end but with solutions that aren’t always the cleanest. By that note, I use the following to make this happen (mostly not according to the array above):
for collection in ${DEPLOYMENT_DIRECTORY_ASSIGNMENT[@]}; do
while IFS=':' read -r first_layer second_layer third_layer repository
do
first_layers+=($first_layer)
second_layers+=($second_layer)
third_layer+=($third_layer)
source_repositories+=($repository)
u_layers=($(echo "${layers[@]}" | tr ' ' 'n' | sort -u | tr 'n' ' '))
done <<< "$collection"
done
This is somewhat static at least, but I add every value to arrays and execute several if-else checks later on for keeping everything sorted when creating layers as directories. For the layers/folders that are equal to each other, I use the option to sort for unique characters to prevent repeating issues.
But because of the fact that this is static from that point, I want to figure out the following:
Can I use a combination of "while IFS=’:’ read -r" supporting the option of dynamically looping through values divided by a ‘:’ when there are different amounts of layers?
Such as:
"layer_1:layer_2:repository"
"layer_1:layer_2:layer_3:repository"
"layer_1:layer_2:layer_3:layer_4:layer_5:layer_6:repository"
"layer_1:layer_2:layer_3:layer_4:layer_5:repository"
I know that Bash isn’t always the most logical choice but when I started these projects, I wanted to challenge myself and have more knowledge about this language.
But what would be the best solution for this?
3
Answers
Use the
-a
option ofread
to write the result into a variable-size array:Here one approach.
To check what is the values of the array with the corresponding field/colum.
Output
In case you simply want to assure that the path defined by the different layers exists, the following would do the trick: