M BUZZ CRAZE NEWS
// news

Best way to read a config file in bash

By Gabriel Cooper

What is the best way to read a config file in bash?
For example, you have a script and aren't willing to fill in all the config manually each time you call the script.

Edit 1: I think I didn't make it clear, so: what I want is... I have a configfile which is like

variable_name value
variable_name value ... 

and I want to read that. I know I could just grep it for the arguments I'm looking for or so... but maybe there's a more intelligent way :)

2

5 Answers

As mbiber said, source another file. For example, your config file (say some.config) would be:

var1=val1
var2=val2

And your script could look like:

#! /bin/bash
# Optionally, set default values
# var1="default value for var1"
# var1="default value for var2"
. /path/to/some.config
echo "$var1" "$var2"

The many files in /etc/default usually serve as configuration files for other shell scripts in a similar way. A very common example from posts here is /etc/default/grub. This file is used to set configuration options for GRUB, since grub-mkconfig is a shell script that sources it:

sysconfdir="/etc"
#…
if test -f ${sysconfdir}/default/grub ; then . ${sysconfdir}/default/grub
fi

If you really must process configuration of the form:

var1 some value 1
var2 some value 2

Then you could do something like:

while read var value
do export "$var"="$value"
done < /path/to/some.config

(You could also do something like eval "$var=$value", but that's riskier than sourcing a script. You could inadvertently break that more easily than a sourced file.)

10

Use source or . to load in a file.

source /path/to/file

or

. /path/to/file

It's also recommended to check if the file exists before loading it because you don't want to continue running your script if a configuration file is not present.

Obviously, I am not the bash specialist here, but the concept should not be different in whatever language you use:

An example

In the example below, you can use a (very) basic script to either set a string, or print a string, as set in your config file:

#!/bin/bash
# argument to set a new string or print the set string
arg=$1
# possible string as second argument
string=$2
# path to your config file
configfile="$HOME/stringfile"
# if the argument is: "set", write the string (second argument) to a file
if [ "$arg" == "set" ]
then
echo "$string" > $configfile
# if the argunment is "print": print out the set string, as defined in your file
elif [ "$arg" == "print" ]
then
echo "$( cat $configfile )"
fi

Then

  • To set a string into your config file:

    $ '/home/jacob/Bureaublad/test.sh' set "Een aap op een fiets, hoe vind je zoiets?"
  • Subsequently, to print out the string, as defined in your "configfile":

    $ '/home/jacob/Bureaublad/test.sh' print
    Een aap op een fiets, hoe vind je zoiets?

Of course, in a real applied script, you need to add a lot of stuff to make sure the arguments are correct, decide what to do when input is incorrect, settings file does not exist etc, but:

This is the basic idea

1

I am using this one...

#!/bin/bash
CFG_FILE=/etc/test.conf
CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g')
eval "$CFG_CONTENT"

Conf file is parsed with sed and then evaluated as simple variable asignments

First sed parsing key values (supports also = surrounded with spaces)

Second sed removes spaces around = sign for valid variable asignment

Futher sed treatment can be added

All other not matching text in conf file will be removed (including # or ; commentary and other)

Be aware that single line shell commands can be also evaluated from this config file!

5
#------------------------------------------------------------------------------
# parse the ini like $0.$host_name.cnf and set the variables
# cleans the unneeded during after run-time stuff. Note the MainSection
# courtesy of :
#------------------------------------------------------------------------------
doParseConfFile(){ # set a default cnfiguration file cnf_file="$run_unit_bash_dir/$run_unit.cnf" # however if there is a host dependant cnf file override it test -f "$run_unit_bash_dir/$run_unit.$host_name.cnf" \ && cnf_file="$run_unit_bash_dir/$run_unit.$host_name.cnf" # yet finally override if passed as argument to this function # if the the ini file is not passed define the default host independant ini file test -z "$1" || cnf_file=$1;shift 1; test -z "$2" || ini_section=$2;shift 1; doLog "DEBUG read configuration file : $cnf_file" doLog "INFO read [$ini_section] section from config file" # debug echo "@doParseConfFile cnf_file:: $cnf_file" # coud be later on parametrized ... test -z "$ini_section" && ini_section='MAIN_SETTINGS' doLog "DEBUG reading: the following configuration file" doLog "DEBUG ""$cnf_file" ( set -o posix ; set ) | sort >"$tmp_dir/vars.before" eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \ -e 's/#.*$//' \ -e 's/[[:space:]]*$//' \ -e 's/^[[:space:]]*//' \ -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \ < $cnf_file \ | sed -n -e "/^\[$ini_section\]/,/^\s*\[/{/^[^#].*\=.*/p;}"` ( set -o posix ; set ) | sort >"$tmp_dir/vars.after" doLog "INFO added the following vars from section: [$ini_section]" cmd="$(comm -3 $tmp_dir/vars.before $tmp_dir/vars.after | perl -ne 's#\s+##g;print "\n $_ "' )" echo -e "$cmd" echo -e "$cmd" >> $log_file echo -e "\n\n" sleep 1; printf "\033[2J";printf "\033[0;0H" # and clear the screen
}
#eof func doParseConfFile

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy