[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: .ini files in bash?



Once upon a time Nate Bargmann said...
> * Cameron Hutchison <camh+dl@xdna.net> [2004 Nov 29 15:15 -0600]:
> > Ok. I got bored and spend a minute writing this:
> > 
> > function savevars()
> > {
> >     for var in "$@" ; do
> >         eval "echo $var=\\\"\$$var\\\""
> >     done
> > }
> > 
> > 
> > Just call it like:
> > savevars VAR1 VAR2 VAR3 >file
> > 
> > then load the vars with:
> > source ./file
> 
> Very nice little code snippet.  Thanks for posting this.  I'm trying to
> learn more about shell scripting and I'm a bit puzzled why there are
> two escaped backslashes.  After removing the obvious ones for quoting I
> get:
> 
> $var=\"$$var\"
> 
> So the embedded quotes have to be escaped again?  I'm still learning
> about the magic of eval, so a little more explanation would be
> appreciated.

The magic of eval is hell to learn. Conceptually it's simple but the
quoting you have to do to get it right ensures multiple iterations of
experimentation. Real gurus would obviously do it in their sleep.

With eval, your argument is going to be parsed by the shell twice - the
first time as it parse the eval line, the second time as eval executes
its argument.

If we step through the above code snippet, we'll assume that var=foo and
that foo=bar.

The first parse becomes

  eval echo foo=\"$foo\"

When eval executes this, we get

  foo="bar"

The reason for the extra backslashes is that we want the double quotes
in the output, so that when the variables are saved to the file. We need
the quotes in the file to preserve the spaces correctly, otherwise when
the file is reloaded, if there are any spaces, the variable assignment
will stop at the first space and anything after that will be assumed to
be a command (like doing "COLUMNS=120 dpkg -l").

The snippet of code I posted is not perfect. It will not properly
preserve backslashes, double quotes, back quotes and dollar signs.

I was working on a proper solution, but put it aside when I got to nine
consecutive backslashes in a sed expression.

If anyone feels like an exercise, the goal is to get a file that can be
sourced by the shell that contains lines of the form:

FOO='bar'

with single quotes surrounding the value. You need to handle the case
where there is a single quote in the string:

The string
World's apart. Who's the boss.

needs to be encoded as:

FOO='World'\''s apart. Who'\''s the boss.'

Have fun.



Reply to: