I'm attempting to run the following query in a bash script, allowing me to check two different object classes for a defined attribute passed from a while loop:


while read -r Field1 Field2 Field3 Field4 Field5 Field6 ;
    ldapsearch -h "`hostname --fqdn`" -p 389 -x -LLL -D "${binddn}" -w "${password}" "'(&(|(ObjectClass=Group1)(ObjectClass=Group2))(Field1Attribute="${Field1}"))'"
done < "$inputfile"
exit 0

Any time I run the command, the variable Field1 passes successfully, but I get a bad search filter error:

ldapsearch -h HOSTNAME -p 389 -x -LLL -D cn=admin,o=services -w BLAH ''\''(&(|(ObjectClass=Group1)(ObjectClass=Group2))(Field1Attribute=FIELD1OUTPUT))'\'''
ldapsearch: ldap_search_ext: Bad search filter (87)

I noticed the command adds (''\') to the beginning and end to the filter. I run the command manually minus the ticks and backslash, the query runs successfully. How is this getting added in?

I've also passed both the search filter as a variable as well as the command itself without success.

  • 1
    Why do you have the single quotes in "'(&(|(ObjectClass...="${Field1}"))'" ? I don't think ldapsearch expects them.
    – ilkkachu
    May 4, 2017 at 18:49
  • The single quotes are required. Otherwise it will complain about the parentheses. You need the parentheses in order to run a boolean filter. May 4, 2017 at 18:54

1 Answer 1


If you do:

ldapsearch -h ... "'(&(this)(that="${Field1}"))'"

The single quotes will be part of of the quoted string, and they will go to ldapsearch. Which doesn't expect them, giving the error. Also, the expansion of ${Field1} is unquoted, since the second double-quote ends the quoting. (Quotes don't nest.)

Your other output looks like the output of Bash's xtrace. It tries to tell you that the argument actually contains a literal quote, but the quoting is rather hard to read.

In this:


we have

''           -- an empty string
\'           -- a literal backslash
'(&(|(...))' -- a quoted string
\'           -- another literal backslash
''           -- another empty string

I suspect what you want is either

ldapsearch -h ... "(&(this)(that=\"${Field1}\"))"

with the double quotes in the string going to ldapsearch, or

ldapsearch -h ... "(&(this)(that=${Field1}))"

without them.

In any case, without the surrounding single quotes. I'm not exactly sure if the double quotes should be there, I can't remember what format ldapsearch rules accept.

As far as I can test in practice, this works fine on one machine:

$ user=itvirta
$ ldapsearch -xLLL "(&(objectClass=shadowAccount)(uid=$user))" 
$ ldapsearch -xLLL '(&(objectClass=shadowAccount)(uid=itvirta))' 
  • That was the trick. Use the double quotes instead of the single quotes passed the command correctly in the script. Thank you! May 4, 2017 at 19:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .