Gavin W. Burris on 20 Sep 2010 06:35:03 -0700

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

Re: [PLUG] Building a command from variables in BASH

Passing variables to sed bit me recently.  I finally figured it out,
proper use of the quotes and escapes, which seems painfully obvious now:


On 09/17/2010 06:39 PM, Edmond Rodriguez wrote:
> Thanks for this:  As arguments,  I very much understand your
> presentation , as I was taking the quotes literally and it seems
> sensitive to how strings/args are built and represented.  I was also
> working under the premise that the structure was such that typing the
> command straight into a command line (with the variables too) would
> work (before going to eval). (but now I would want to experiment more
> with that).
> You present some very nice execution issues that can creep up on
> someone, which I have spent some time playing with.  Thanks for your
> comments.
> Here is something new I tried while trying your scripts, but probably
> not full proof?  I did not investigate further.  Just playing around a
> little with the case you presented.     It worked in this case.  Maybe
> you have some comments on what would be wrong with doing this:
> The idea here would be to get away from the concatenated args and just
> produce a string to work off of.
>     args="-e 's/foo bar/far sar/g'"
>     eval `echo "argtest $args"`
> I guess this is getting into the "conjured up code" idea you were referring to.
> I was trying think of what problems "echo" might create.  I tried the
> following which seemed to work OK too:
> args="-e 's/foo bar/far sar/g' '\n' '\`hello\`' 'abc def'"
> eval `echo "argtest $args"`
> Thanks for improving my bash knowledge!
> Edmond
>> just with an extra interpretation/expansion step to get there.  this is safe
>> from embedded quotes and shell metacharacters, but will be problematic
>> if you have whitespace in the variable.  consider the following for
>> why it might not be desirable for the OP:
>>        argtest(){
>>          local i
>>          i=1
>>          while [ $# -gt 0 ]; do
>>            echo "argument $i: ==$1=="
>>            i=`expr $i + 1`
>>            shift
>>          done
>>        }
>>        args="-e 's/foo bar/far sar/g'"
>>        argtest $args # or eval argtest \$args if you like :)
>> this will pass 4 arguments to argtest instead of 2.  quoting $args would
>> mean only 1 argument.  to preserve that information the best way to do so
>> is to set the arguments as positional parameters (set+eval) and then
>> expand them with the special syntax "$@", which expands to each individual
>> parameter, quoted.  but if you're using set+eval, then you need an extra
>> round of escaping/quoting (basically you'd be quoting them individually
>> ahead of time).  that's what the articles linked in the last mail are
>> all about.
> ___________________________________________________________________________
> Philadelphia Linux Users Group         --
> Announcements -
> General Discussion  --

Gavin W. Burris
Senior Systems Programmer
Information Security and Unix Systems
School of Arts and Sciences
University of Pennsylvania
Philadelphia Linux Users Group         --
Announcements -
General Discussion  --