0

I want to create a Bash script that creates config files. I want this file to be able to be called by another script that sets parameters in the config file. (For additional but unrelated info to keep in mind, the Bash script also runs a Matlab program that reads in that config file).

So for example, I want to produce a config file with:

Variable1 = 52

Variable2 = 77.

I want a script, say "MainScript" that physically produces such a config file, and the variables are set by another script "CallScript" that calls MainScript. How do I go about implementing this?

1
  • 7
    Welcome to the site. Can you show us what you have tried so far?
    – Haxiel
    Oct 26, 2018 at 5:23

1 Answer 1

2

Don't know whether namely "CallScript" that calls "MainScript" is needed, but here is a script, which can do what is required (say it would be "MainScript"; if you'd like, you can put its calling: bash MainScript.sh <args> — into another file, say "CallScript").

Light-version

$ cat MainScript.sh
#!/bin/bash
CFG_FILE="matlab.cfg"

function make_config() {
     arr=("$@") 

     echo -n "" > $CFG_FILE
     for i in "${!arr[@]}"; do
         echo "Variable$((i+1)) = ${arr[i]}" >> $CFG_FILE;
     done
}

make_config $@

Here is the "CallScript":

$ cat CallScript.sh
bash MainScript.sh 1 11 27 23 44

Now change permissions of the "CallScript.sh":

$ chmod +x CallScript.sh

And you can launch it in a such way:

$ ./CallScript.sh

to produce a config file like this:

$ cat matlab.cfg 
Variable1 = 1
Variable2 = 11
Variable3 = 27
Variable4 = 23
Variable5 = 44

More complicated version

On the other hand, if you want to have (pre-defined) different custom names of variables, you can do smth like this:

$ cat MainScript.sh
#!/bin/bash

CFG_FILE="matlab.cfg"
MLAB_VARS=("CustomVariable1" "CustomVariable2" "VeryCustomVariable11")

function make_config() {

    arr=("$@") 
    var_length=${#MLAB_VARS[@]}
    entered_length=$#
    [ $var_length -gt $entered_length ] && \
        echo "Please enter more than or equal $var_length number of values for setting variables" && \
        usage && exit 1
    echo -n "" > $CFG_FILE
    for i in "${!MLAB_VARS[@]}"; do
        echo "${MLAB_VARS[i]} = ${arr[i]}" >> $CFG_FILE;
    done
}

function usage() {
cat << EOF

Usage:
    MainScript.sh [value [value [value [...]]]]

        where each value will be used to set corresponding variable
EOF
}

make_config $@

then

bash MainScript.sh 1 11 27

will produce

$ cat matlab.cfg 
CustomVariable1 = 1
CustomVariable2 = 11
VeryCustomVariable11 = 27

and

$ bash MainScript.sh 1 11
Please enter more than or equal 3 number of values for setting variables

Usage:
    MainScript.sh [value [value [value [...]]]]

        where each value will be used to set corresponding variable

Complex version

If you want to just pass all map of variables-values dynamically, you can use following approach:

$ cat MainScript.sh
#!/bin/bash

CFG_FILE="matlab.cfg"


usage() {
cat << EOF

Usage:
    MainScript.sh [value [value [value [...]]]]

        where each value will be used to set corresponding variable
EOF
}


make_config() {

    arrays_str="${@}"

    array_var="${arrays_str#*#}"
    # create new associative array with varname-values pairs from string
    eval "declare -A mlab_vars=${array_var#*=}"
    array_ord="${arrays_str%#*}"
    # create new array with vars orders from string
    eval "declare -a mlab_ords=${array_ord#*=}"

    echo -n "" > $CFG_FILE
    for key in "${mlab_ords[@]}"; do
        echo "$key" = "${mlab_vars[$key]}" >> $CFG_FILE;
    done
}


declare -A var_array
declare -a var_order

for arg in "$@"
do
    case $arg in
        -*=*|--*=*)
            arg_name="${arg%=*}"
            arg_name="${arg_name#*-*}"; arg_name="${arg_name#-}" 
            var_array["${arg_name}"]="${arg#*=}"
            var_order+=( "${arg_name}" )
            shift # past argument=value
        ;;
        h|--help)
            usage
            exit 0
        ;;
        *)
            # unknown option
            shift
        ;;
    esac
done

# convert associative array to string
assoc_array_string="$(declare -p var_array)"

assoc_array_orders="$(declare -p var_order)"

make_config "$assoc_array_orders # $assoc_array_string"

Then use it such a way:

$ bash MainScript.sh --CustomVar=1230 --Var1=5613 --Var2="MatLab Rabbit" --Var3="1328"

And the results will be:

$ cat matlab.cfg 
CustomVar = 1230
Var1 = 5613
Var2 = MatLab Rabbit
Var3 = 1328

Although, don't forget to check your bash version:

$ bash --version   

It must be at least version 4 to have associative arrays

1
  • BTW, I think there are more friendly languages for such a task, e.g. Python. :)
    – kenichi
    Oct 26, 2018 at 13:53

You must log in to answer this question.