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
    You'll have to show what kind of configuration you mean. Provide an example.
    – muru
    Mar 8, 2016 at 16:25
  • See also a very similar question on the Unix & Linux StackExchange.
    – Michael
    Dec 12, 2018 at 21:03

5 Answers 5


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


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:

if test -f ${sysconfdir}/default/grub ; then
  . ${sysconfdir}/default/grub

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
    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.)

  • That's a great way, i could use sed substitute whitespace for "="
    – IcyIcyIce
    Mar 8, 2016 at 22:52
  • 1
    @IcyIcyIce Just don't. Why can't you write it with = from the start?
    – muru
    Mar 8, 2016 at 22:53
  • 1
    @IcyIcyIce That's how it's supposed to be. You can use shell code in the various files in /etc/default - and mostly to good use. If your clueless user has access to configuration for something running as root, it's already a lost cause.
    – muru
    Mar 8, 2016 at 22:55
  • 1
    @IcyIcyIce get your teachers to clarify what they want. A part of learning to develop software is getting to know the requirements clearly.
    – muru
    Mar 8, 2016 at 23:00
  • 1
    @IcyIcyIce see update.
    – muru
    Mar 8, 2016 at 23:09

Use source or . to load in a file.

source /path/to/file


. /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:


# argument to set a new string or print the set string
# possible string as second argument
# path to your config file

# if the argument is: "set", write the string (second argument) to a file
if [ "$arg" == "set" ]
echo "$string" > $configfile 
# if the argunment is "print": print out the set string, as defined in your file
elif [ "$arg" == "print" ]
echo "$( cat $configfile )"


  • 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

  • thanks, i'm just updating the question i think i didnt make it clear... but in simple cases this would work like a charm ofc
    – IcyIcyIce
    Mar 8, 2016 at 20:40

I am using this one...


CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g')

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!

  • 4
    Useless use of cat. Why do you invoke sed twice back-to-back? You can chain sed commands like so: sed -r '/[^=]+=[^=]+/!d;s/\s+=\s/=/g' Feb 24, 2017 at 15:16
  • Also, this sed command will generate an empty output for the sample configuration file entries in the question. -1 Feb 24, 2017 at 15:18
  • 2
    Another possible improvement: use the . command and process redirection instead of temporary variables to hold the output of the sub-process: . <(sed ... "$CFG_FILE") Feb 24, 2017 at 15:32
  • 1
    Of course my example uses key=value like config file. It is better practise than "key value". Using key=value my example works. Your chaining of sed commands is better, I admit, but source command expects file so we can use: eval $(sed -r '/[^=]+=[^=]+/!d;s/\s+=\s/=/g' "$CFG_FILE"), which is way better to understand what there is going on.
    – smARTin
    Feb 27, 2017 at 14:40
  • 1
    Yes, . expects a file and process substitution is expanded to a file. . <(echo echo foo) works just as expected in Bash v4.3.11. In small examples it probably won't matter. I'd rather not pass multiple kilobytes through command substitution though. Feb 27, 2017 at 15:00
# 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 : http://mark.aufflick.com/blog/2007/11/08/parsing-ini-files-with-sed
    # set a default cnfiguration file

    # 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

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.