I use the ConfigObj Python library for this. If you do this, it does require writing Python to interface with the config files. I typically have a default_conf
file which has default values, and I can selectively override these settings with some other file, say user_conf
Here is the code I am currently using as an example. The second half of the function is validation, which is important, but you can ignore it to a first approximation. For usage you do
conf = get_conf()
ip = conf["ip"]
In your case, I guess the server file is the one that overrides, though more usually it is the user file which overrides the system file. That is certainly the user convention in Unix-type systems.
To write a ConfigObj object to file, to a first approximation you do (if config
is your object as in the script below)
config.filename = filename
config.write()
So you could modify the function below to write to a file instead of returning the config object if you want. See Writing a Config File for a little more detail.
def get_conf():
import configobj, validate, sys
try:
config = configobj.ConfigObj('default_conf', configspec='conf.validate', raise_errors=True)
except configobj.ConfigObjError:
print "ERROR FOR CONFIG FILE 'default_conf':"
raise
try:
user = configobj.ConfigObj('user_conf', configspec='conf.validate', raise_errors=True)
except configobj.ConfigObjError:
print "ERROR FOR CONFIG FILE 'user_conf':"
raise
config.merge(user)
#This is config file validation
fdict = {'check_list_of_list_of_integers': list_of_list_of_integers}
validator = validate.Validator(fdict)
results = config.validate(validator, preserve_errors=True)
if results != True:
for entry in configobj.flatten_errors(config, results):
# each entry is a tuple
section_list, key, error = entry
if key is not None:
section_list.append(key)
else:
section_list.append('[missing section]')
section_string = ', '.join(section_list)
if error == False:
error = 'Missing value or section.'
print section_string, ' = ', error
sys.exit(1)
return config
UPDATE 16th December 2015: Something like YAML is probably a better general solution. I recommend that instead of ConfigObj. For one thing,
it's more flexible.