Snalk

Snalk » OS Tutorials » Unix » Common File Format for Storing Settings

Reply
  #1 (permalink)  
Old 10-31-2008, 11:41 AM
Junior Member
 
Join Date: Oct 2008
Posts: 14
Post Common File Format for Storing Settings

Common File Format for Storing Settings



You can represent just about any system setting by a name/value pair. The value may be a number, a string, or a list of values. Name/value pairs are also quite easy to read and write in any environment. I always use a format that can be directly used by the bash shell (actually, this format can be directly read by every shell). Here is an example:

ip_addr='192.168.2.3'
netmask='255.255.0.0'
dns_servers='192.168.0.2 192.168.0.3'


There are certain restrictions (as imposed by the bash shell) on the variable names, but they should be easy to control. When the value is enclosed in single quotes as shown, it can contain any character—except for single quotes. In order to avoid a corrupt configuration file, you cannot allow single quotes to be contained in the values. If you don't want this restriction, you can use outer double quotes if there are single quotes present in the value, but then you must escape any double quotes, dollar signs, or backslashes within the string.

When you are manually creating a file that contains shell variables, it is easy to try and use shell substitution. You need to avoid this, of course, if the file will be read by other programs (such as ones written in Perl) that will not process the file the same way a shell would. In addition, if a user will be modifying the values through the web or another user interface, they may be confused by the presence of any variable substitutions.

Reading in bash

Reading this type of file from bash is easy. You just source the configuration file. Here is an example:


source /usr/local/etc/system.conf

Writing in bash

This type of configuration file is easy to write in bash. One method involves creating the file from scratch, like so:

FILE="/usr/local/etc/system.conf"

add_value() {
eval echo "$1=\"'\${$1}'\"" >> $FILE
}

# Empty the file
>$FILE

# Create entire file
add_value ip_addr
add_value netmask
add_value dns_servers


The add_value function expects one parameter. This is the name of a variable that may or may not have a defined value. So, if the environment variable $ip_addr is not defined, the following line will be added to the specified configuration file:

ip_addr=''

But, if $ip_addr contains the value 192.168.1.1, that value will be used in the file:

ip_addr='192.168.1.1'

You could also create a function that will work with a non-empty file. It can remove the variable from the current configuration file (if it is there), and then re-add the variable with the new value:

FILE="/usr/local/etc/system.conf"

set_value() {
grep -v "^$1=" $FILE > $FILE.tmp
mv $FILE.tmp $FILE
eval echo "$1=\"'\${$1}'\"" >> $FILE
}

# Update just the IP address
set_value ip_addr


Remember that the value may not contain a single-quote character (').

Reading in Perl

It is also pretty easy to read this type of file in Perl. Here is a function that can read any configuration file of this format; it returns a reference to a hash table containing the name/value pairs.

sub read_file ($) {
my ($file) = @_;
my %ret;
open(FILE, $file) or return undef;
while (my $line = <FILE>) {
chomp($line);
next if ($line =~ /^\s*$/); # skip blank lines
next if ($line =~ /^\s*#/); # skip comments

# Split into name and value
my ($name, $value) = split('=', $line, 2);
next unless ($name and $value);

# Remove single-quotes
$value =~ s/^'//;
$value =~ s/'$//;

# Store value
$ret{$name} = $value;
}
close(FILE);
return \%ret;
}


You can access the values as follows:

my $data = read_file('/usr/local/etc/system.conf');
print "IP Address: $data->{'ip_addr'}\n";


Writing in Perl

Writing this type of file in Perl is easier than writing it in bash. Here is a function that writes the entire file out using the hash reference passed into the function:

sub write_file ($$) {
my ($file, $data_ref) = @_;
open(FILE, ">$file") or return 0;
foreach my $name (keys %{$data_ref}) {
print FILE "$name='$data_ref->{$name}'\n";
}
close(FILE);
return 1;
}
Reply With Quote
Reply

Bookmarks

Tags
file format, format, settings, storing settings, unix

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump



All times are GMT. The time now is 06:57 AM.
Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.