Passing variables as arguments to commands in a shell script

Passing variables as arguments to commands in a shell script

Post by shahidsheik.. » Mon, 31 Oct 2005 17:12:36



Hi all,

I am a newbie with shell scripting and not sure if I am going about
this the right way.

What I have is:

  ADGroup="Domain Admins"
  cmd="ldapsearch -x -LLL"
  filter="CN=\"${ADgroup}\" member"
  ${cmd} ${filter}

I want the command to run as

  ldapsearch -x -LLL CN="Domain Admins" member

Instead what actually runs is

  ldapsearch -x -LLL 'CN="Domain' 'Admins"' member

How can I setup the variables so that I don't get the extra single
quotes when the command runs?

What also will work is

    ldapsearch -x -LLL CN='Domain Admins' member

But I have tried several combinations and couldn't get any to work with
the way my variables are setup.

Thanks,

Shahid

 
 
 

Passing variables as arguments to commands in a shell script

Post by Chris F.A. Johnso » Mon, 31 Oct 2005 19:07:12



> Hi all,

> I am a newbie with shell scripting and not sure if I am going about
> this the right way.

> What I have is:

>   ADGroup="Domain Admins"
>   cmd="ldapsearch -x -LLL"
>   filter="CN=\"${ADgroup}\" member"
>   ${cmd} ${filter}

> I want the command to run as

>   ldapsearch -x -LLL CN="Domain Admins" member

   Then why don't you do that, instead of using variables which
   introduce quoting problems?

Quote:> Instead what actually runs is

>   ldapsearch -x -LLL 'CN="Domain' 'Admins"' member

> How can I setup the variables so that I don't get the extra single
> quotes when the command runs?

> What also will work is

>     ldapsearch -x -LLL CN='Domain Admins' member

> But I have tried several combinations and couldn't get any to work with
> the way my variables are setup.

    Why do you need variables?

    If you need a flexible method of calling the command, encapsulated
    it in a function instead, passing variables as arguments.

--
  Chris F.A. Johnson                   | Author:
  <http://cfaj.freeshell.org>          |      Shell Scripting Recipes:
  Any code in this post is released    |  A Problem-Solution Approach,
  under the GNU General Public Licence |                 2005, Apress

 
 
 

Passing variables as arguments to commands in a shell script

Post by Enrique Perez-Terro » Mon, 31 Oct 2005 20:22:12



> Hi all,

> I am a newbie with shell scripting and not sure if I am going about
> this the right way.

> What I have is:

>   ADGroup="Domain Admins"
>   cmd="ldapsearch -x -LLL"
>   filter="CN=\"${ADgroup}\" member"

I suppose you mean ${ADGroup} (uppercase G)

Quote:>   ${cmd} ${filter}

You want

     eval $cmd $filter

The reason is the order of events: The shell splits the line in words,
and removes quotes in the process. It finds two words ${cmd} and ${filter},
but no quotes. Then it inspects each word for parameter expansions, and finds
one in each word. This step introduces quotes into the words, but at this
point the shell does no longer treats the quotes specially. Finally, the
shell splits the words looking for spaces introduced in parameter expansions
in unquoted words.

Using eval, you force the shell to look at the resulting line once again
and discover the quotes introduced in the parameter expansion.

But depending on the actual application, there could be a severe security
problem using "eval".  If, for instance, the actual contents of the
variable ADGroup comes from a source controlled by somebody else, like
user input, a web form, etc, then a malicious user can put something clever
in his input.

For instance, if

   ADGroup='";rm -rf /;": '

then the script will remove all files from your system.

To avoid that,

   ADGroup="${ADGroup//\\/\\\\}"
   ADGroup="${ADGroup//\"/\\\"}"
   ADGroup="${ADGroup//\$/\\\$}"

This will add a backslash in front of each occurrence of \ " or $ in
ADGroup. Then eval will only see quoted characters and do nothing strange.

Don't change the order of these lines, the first one must be first.

It requires a sufficiently modern shell, that support this kind of
substitutions.

You may be better served by doing what you do in the line filter=...
directly in the final line:

   $cmd "CN=\"${ADgroup}\"" member

In this way, the shell will find three words in the first step, one of which
is quoted. It will expand the parameters, and split the first word, but not
the second, since the second was quoted.

-Enrique