2

I have a config file containing the following:

variable1 = 25
variable2 = 36

I want to parse this file in a Bash script and set each respective variable to its proper value within my script. How do I do this? I have the code at the bottom, but all this does is display the content. I want to actually set the variables and their values in my script, then check whether a certain variable fulfills a condition, such as (pseudocode):

if "variable1 = 25", then echo "confirm"

IFS="="
while read -r name value
do
echo "Content of $name is ${value//\"/}"
done < filename

2 Answers 2

3

One option is to fix up the syntax in the file and have the shell parse the file directly. The disadvantage is that the shell must be able to parse valid syntax, and you're essentially running the configuration file as code in the content of the running script.

Fortunately you've tagged with bash, which is good because that shell supports associative arrays. This allows you to read in the values without having the shell attempt to parse or evaluate them, which in turn means you don't need to trust the content of the configuration file quite so much.

Assuming configuration settings are one-per-line you can read them in with code like this

#!/bin/bash
#
declare -A config
while IFS=$'[ \t]*=[ \t]*' read -r name value
do
    echo "Read name=$name, value=$value" >&2
    config[$name]="$value"
done

And you can reference them using "${config[$name]}" references like this

echo "variable1=${config[variable1]}, variable2=${config[variable2]}." >&2

The IFS=$'[ \t]*=[ \t]*' construct tells the read verb to ignore whitespace surrounding the = symbol, so that fruit=pear and fruit = pear are equivalent.

0

I would suggest a different approach. Your variables file is very similar to an assignment statement in shell syntax. The only problem is the whitespace around the assignment operator (you can find more details on that here). First, you could use a sed command like the one below to fix the whitespace:

$ cat vars.txt
variable1 = 25
variable2 = 36

$ sed -i 's/ = /=/' vars.txt

$ cat vars.txt
variable1=25
variable2=36

Once you have done this, just source the file to set all the variables as you need:

#!/bin/bash
source vars.txt
echo "Variable 1: $variable1, Variable 2: $variable2"

Which would give you the output:

Variable 1: 25, Variable 2: 36

As roaima notes in the comments, there is a security problem involved with this approach. When you source your file, you're essentially running it as a shell script (Executing a script vs Sourcing a script is explained here). This means that you have to trust the contents of that file. If a malicious user or process is able to edit the file, you could end up executing arbitrary commands.

Also as roaima notes, quoting would be required if the values for the variables contain special characters. This answer was written specifically for the data set in the question, which only has numeric values for the variables. It cannot be easily extended for other types of values.

3
  • 2
    Would be worth warning that because the shell would be parsing the configuration file, the target code needs to be able to trust anyone/anything that can edit the configuration file. Furthermore, the shell would need its special characters escaped - consider text = `Give me $5 for my time'. Mar 9, 2019 at 10:21
  • Agreed with @roaima. Your solution works in this particular case, but that fact remains circumstantial. Roaima's answer, despite relying on a bashism (i.e. associative arrays), is generic, safe and on both counts should be the selected answer. No offense meant or intended.
    – Cbhihe
    Mar 9, 2019 at 18:09
  • @Cbhihe None taken. This approach was what occurred to me first, so I simply wrote it down as an answer. It does work for this specific case, so I think I'll leave it here as one possible solution to the problem :-).
    – Haxiel
    Mar 11, 2019 at 18:10

You must log in to answer this question.