Today I was looking into how to add a configuration file to a script.
And this how I implemented it:
parse_ini()
{
cat <<EOF | python3
from configparser import ConfigParser
config = ConfigParser()
config.read("$1")
for section in config.sections():
print(f'declare -A {section}')
for key, value in config.items(section):
print(f'{section}[{key}]="{value}"')
EOF
}
The parse_ini
use an inline Python
scripts to parse the
configuration file, then convert it to a bash script that is printed
on the standard output.
Each section is translated to an associative array (an associative array variable in bash is similar to a dictionary in Python).
So if you have this config file, named config.ini
:
[CONFIG]
MY_KEY="Hello"
You can access to the value of MY_KEY
in bash
with:
source <(parse_ini config.ini)
echo ${CONFIG[my_key]}
> Hello
Advanced example
This example demonstrate how you can use a variable to select from which section you want to get the value from a key.
We will create a translatable hello-world script:
First we create a hello-world-translation.ini
file with:
[FR]
HELLO_WORLD=Bonjour le monde
[EN]
HELLO_WORLD=Hello World
Then we create the hello-world.sh
scripts as follows
#!/usr/bin/env bash
# This script just echo "Hello World" in the terminal, but
# you can change the language by settings the first parameter the `FR`
# In order to it to work, we need to create a name reference with declare -n
declare -n LANG=${1:-EN} # Use english by default
# Note: using normal
parse_ini()
{
cat <<EOF | python3
from configparser import ConfigParser
config = ConfigParser()
config.read("$1")
for section in config.sections():
print(f'declare -A {section}')
for key, value in config.items(section):
print(f'{section}[{key}]="{value}"')
EOF
}
source <(parse_ini hello-world-translation.ini)
echo ${LANG[hello_world]}
And finally, use it from the console:
chmod +x hello-world.sh
./hello-world.sh
> Hello World
./hello-world.sh FR
> Bonjour le monde
./hello-world.sh EN
> Hello World
Of course, you can call multiple time the parse_ini
function to read
from multiple file. Section will be merged together and value overwritten.
Source and useful links
The solution is heavily inspired from this serverfault entry
You can also learn how to use an associative array or what is a nameref variable
Dependencies
The code require at least Bash 4.3
and should work with any Python 3
version.