Reputation: 4150
Okay so I JUST started bash scripting two weeks ago, and I ran into an issue last week that I just cannot fix. I'll describe my problem as best I can and I've included my script. I welcome any criticisms on what I am doing wrong with this code; Actually, I implore you to please provide as much criticism on my technique as you can so that I can learn from it.
I installed a new Zimbra Collaboration Suite for my company, and am in the process of migrating user accounts. I am trying to create a bash script to do the following:
zmprov ca
command.zmprov
command.Here is my script:
#!/bin/bash
#Use this script to pull user information from Company Active Directory
argerror="Usage: company-ldap domain username"
if [ "$1" == "local" ]; then
domain=MYLOCALDOMAIN
ou=MAIN
else
echo "$argerror"
exit
fi
if [ -z $2 ]; then
echo "$argerror"
exit
else
user=$2
fi
password=P@ssw0rd
ldapsearch -h 1.2.3.4 -p 389 -D "cn=$user,ou=$ou,dc=$domain,dc=COM" \
-w "$password" -b "ou=$ou,dc=$domain,dc=COM" \
"(&(name=*)(mail=*)(givenName=*)(sn=*))" \
'name' 'mail' 'givenName' 'sn' -LLL -S 'name' |
grep -B 1 'name\|mail\|sn\|givenName' |
grep -v '^dn:' | tr '\n' ' ' |
sed -e 's/ -- /\n/g' |
awk '{s=""; for (i=1;i<NF;i++) s = s $i " ";print $NF " " s}' |
sed -e 's/sn: /sn '\''/g' |
sed -e 's/ givenName: /'\'' gn '\''/g' |
sed -e 's/ mail: / /g' |
sed -e 's/ name: /'\'' displayName '\''/g' |
awk '{print "ca " $0"'\''"}' |
sed -e 's/ '\''$/'\''/g' |
awk '{($2 = $2 " tempzimbrapw1234"); print $0}' |
while read line ; do zmprov $line ; done
I call the command with this:
./zdap local admin
Requested edit...
The zmprov
command for a given user (Joe Smith) looks like this:
zmprov ca [email protected] tempzimbrapw1234 sn 'Smith' gn 'Joe' displayName 'Joe Smith'
However, when I run the zdap bash script I wrote, I expect to get a create account confirmation from Zimbra, but instead get this message:
zimbra@CPU-00154:~$ ./zdap local admin
usage: createAccount(ca) {name@domain} {password} [attr1 value1 [attr2 value2..
For general help, type : zmprov --help
Unfortunately I have tried too many solutions to list them all here. I've spent a week reading manuals, forums, etc. and have tried tons of tweaks, adjustments, new commands, etc. but to no avail.
Once again, I would greatly appreciate any criticisms regarding my script or overall method for accomplishing this. Please try to include examples with your suggestions so that I can see what I'm doing wrong here. Thank you in advance.
I thought I should include the format of the LDAP query result so you can see what my command is working with:
dn: CN=admin,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: admin
mail: [email protected]
--
dn: CN=Jane Doe,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: Jane Doe
mail: [email protected]
--
dn: CN=Joe Smith,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: Joe Smith
mail: [email protected]
I managed to work out the issue using the printf
command (special thanks to rici for that suggestion). The output from printf was this...
<|zmprov|> <|ca|> <|[email protected]|> <|tempzimbrapw1234|> <|#|> <|sn|> <|'Smith'|> <|gn|> <|'Joe'|> <|displayName|> <|'Joe|> <|Smith'|>
As you can see, the value of the last argument (displayName) was being misinterpreted.
Upvotes: 0
Views: 765
Reputation: 241861
It would still be helpful if you included (2) from my first comment, especially the printf
version:
printf '<|%s|> ' $line && printf '\n'
That printf
statement will put <|
|>
around each argument, which makes it possible to see the difference between:
<|zmprov|> <|ca|> ... <|displayName|> <|'Joe Smith'|>
and
<|zmprov|> <|ca|> ... <|displayName|> <|'Joe|> <|Smith'|>
But I venture to guess that what you really want is:
<|zmprov|> <|ca|> ... <|displayName|> <|Joe Smith|>
Shell script quoting takes a bit of time to get your head around. Tools like that printf statement will help. Experiment a bit with simple commands. Pay attention to how variables are expanded. (And note that quotes in the values of variables are just ordinary characters.) Also make sure you understand the difference between zmprov $line
and zmprov "$line"
.
Finally, read the bash FAQ on quoting: http://mywiki.wooledge.org/BashFAQ/050
Also, sed
can execute more than one command in a single invocation, and awk
can do most of the things sed
can do. I suspect you could simplify that massive line into a simple awk
program.
Upvotes: 1