bash variable substitution...

Paul Bryan pa_bryan at yahoo.co.uk
Fri Jan 3 01:18:06 EST 2003


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Wed, 1 Jan 2003 12:08, Peter Lavender wrote:
> Now when it runs I get an error about invalid DN.. which is openldap
> complaining here.
>
> Yet, if I copy and paste the command from the command line, it works
> fine.

Me too...

>
> The problem here I think is the use of the single quotes around the
> filter where I want to put the parameter from the command line in. Or
> how I'm trying to execute the variable $cmd and get the output.
>
> Pete

It's the single quotes alright. On the command line, the string you enter 
isn't enclosed in double quotes. In your script however, the single quotes 
are enclosed in the double quotes and bash treats that as a literal quote. 

If you look at the result of the ldap search you'll notice the filter is 
something like '(|(sn...)'. Notice the single quotes around the text. When 
you run the search from the command line, have a look at the filter. No 
quotes! This is because bash strips them before passing the argument (without 
any sort of expansion) to ldapsearch. That's the point of the quotes on the 
command line.

In your script though, you don't want to pass literal quotes. You just want 
to protect the arguments from any sort of expansion as they contain shell 
metacharacters.

You should be able to just drop the single quotes and away you go. This is 
pretty safe because it's harldy likely that any file will match 
"(|(sn=*...)". That doesn't mean you won't ever change it to something that 
may match files or create some files with really interesting names though!

So, you still need ot prevent expansion of the filter just in case (better to 
be paranoid now and know you don't have to worry later). 

What you need to do is seperate out things into seperate variables. Try this:

cmd="ldapsearch -x -s sub -b ou=People"
filter="(|(sn=${name}*)(cn=*${name}*))"

The the line to run is this:

${cmd} "${filter}"

By putting $filter into double quotes, you prevent any shell expansion. This 
way, whatever is in $filter will be passed literally to ldapsearch. A point 
to note though is that the entire string in $filter will be treated as a 
single argument to ldapsearch. So if you want to seperate out the ou=People 
part you'll have to store that in it's own variable.

A bit long winded I know, but teach a man to fish...

ps. to be really safe, and harder to read therefore better code ;), try:

filter='(|(sn='"${name}"'*)(cn=*'"${name}"'*))'

Everything except variable expansion inside single quotes. This is okay, bash 
will quote, expand, strip and do all it's magic and the result will be stored 
as a single string in $filter.

- -- 
Paul Bryan
E-Mail: pa_bryan at yahoo.co.uk
 
PGP Key
http://www.keyserver.net:11371/pks/lookup?op=get&search=0xB1D405DA
The abuse of greatness is when it disjoins remorse from power.
		-- William Shakespeare, "Julius Caesar"
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE+FEoh3qGyTLHUBdoRAnCBAJ9LJ2vQ3ZfKWvCTwDeo9lBwpJpr4ACeP/Zl
VlwcxdikWwISorvh1dYqH8M=
=Fwan
-----END PGP SIGNATURE-----



More information about the linux mailing list