create zsh function with argument for ldapsearch

I have a couple commands I can run directly on the command line without issue, when I run them and replace $1 with the actual group name I want to check in LDAP. Now I want to turn it into a parameterized function, and I can’t get an error message or an echo to print anything out.

How do I turn the code below into a function I can invoke in zsh by adding it to my .zshrc on the command line? (Slightly tweaked for public posting)

alias ldapuserlookup=" /usr/bin/ldapsearch -LLL -x -h -s sub -b 'ou=Groups,' '(cn=$1)' memberuid | sed 's/memberuid: //g')"

Expected output:


This has to have been asked a million times, but I just don’t know what keywords to put into a search that will give me a helpful example. So many are for bash, or don’t work with whatever I’m doing.

Asked By: ADataGMan


You can scroll down to the end for the solution, but because it is important to understand what is actually happening, here is the full breakdown.

The answer is three-fold:

1. The command you provided contains an error: There is an extra ) at the end of the sed argument resulting in the following error output:

zsh: parse error near `)' 

(I am guessing this may be a left over from perhaps trying to use $(...) syntax)

2. You are using an alias to execute a command expected to operate on a user-provided argument.In this case you want to use a function instead.

Aliases are essentially just shell helpers and their intended purpose is string substitution of command names, often with appended option flags , for example: alias ll='ls -al' , alias grep='grep --color=auto' etc.". Additionally, aliases have multiple caveats that can easily break command behavior, but thse go beyond the specific answer to this question.

In your particular case you want to use a function instead as these are meant to both accept command arguments and parse them as desired. They are the best of both worlds as they operate in a similar way to aliases – where they can be initialized both globally as well as on the fly inside of one specific terminal – but also have the versatility of a real script, yet without requiring the additional hassle of creating a script file .

In order to reformat your alias as a function you would declare it like so (NOTE: This is not yet the full solution):

# It is standard practice to use '_' as separator function names 
 /usr/bin/ldapsearch -LLL -x -h -s sub -b 'ou=Groups,' '(cn=$1)' memberuid | sed 's/memberuid: //g'

NOTE: Prepending echo to a command is a good way of checking how the shell is parsing that specific command. One can also use set -x for full debug output, but this can be quite verbose.

Using the following two declarations with prepended echo will illustrate the difference in parsing of the provided argument:

alias testalias='echo  "/usr/bin/ldapsearch -LLL -x -h -s sub -b ou=Groups, (cn=$1) memberuid " '
   echo "/usr/bin/ldapsearch -LLL -x -h -s sub -b ou=Groups, (cn=$1) memberuid " }
  • BAD: Using the declared alias and running testalias argtest we obtain:
 /usr/bin/ldapsearch -LLL -x -h -s sub -b ou=Groups, (cn=) memberuid  testarg

This is clearly not the desired behavior, as the provided argument gets appended at the end of the command instead of where our command is told to expect the it ( cn=$1 )

  • GOOD: Using the function test_func argtest we get:
 /usr/bin/ldapsearch -LLL -x -h -s sub -b ou=Groups, (cn=testarg) memberuid

**As you can see, our declared function was able to parse our command line argument argtest and then placed at the correct desired position inside of our command, namely as an argument to cn= **

3. You are using ' around the variable parameter, and both bash and zsh obey the rule where variables enclosed in ' do not get expanded, but those enclosed inside " do.

Here are is how your command (again dropping the pipe for clarity) – even if placed inside of a function – will be parsed depending on the used variable enclosure:

  • Using single-quotes ' around variable inside the function
    echo "/usr/bin/ldapsearch -LLL -x -h -s su -b 'ou=Groups,'"  '(cn=$1)' memberuid 

Executing test_func argtest


/usr/bin/ldapsearch -LLL -x -h -s su -b 'ou=Groups,' (cn=$1) memberuid

  • Reformatting the function with double-quotes " instead (leaving the old unneeded ' quotes, to show that " will override them)
    echo "/usr/bin/ldapsearch -LLL -x -h -s su -b 'ou=Groups,'"  "'(cn=$1)'" memberuid

Executing test_func argtest


/usr/bin/ldapsearch -LLL -x -h -s su -b 'ou=Groups,' '(cn=argtest)' memberuid

Full solution:

The full function declaration(echo removed, sed pipe appended, double quotes used) which should give you the desired behavior is:

ldap_userlookup () {
       /usr/bin/ldapsearch -LLL -x -h "" -s "sub" -b "ou=Groups," "(cn=$1)" memberuid | sed 's/memberuid://g'

Once you test it and it works, you can append it to either your main ~/.zshrc where it will be loaded into every zsh terminal window, or you can create a separate ~/.zsh_functions file, put this and other custom function defintions inside it, and then use source ~/.zsh_functions to load them into your shell as needed.

Answered By: Neticegear
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.