Как мне отформатировать, перечислить и выполнить каждую строку из результата запроса LDAP?
Итак, я ПРОСТО начал использовать bash-скриптинг две недели назад, и на прошлой неделе я столкнулся с проблемой, которую просто не могу исправить. Я опишу свою проблему как можно лучше, и я включил свой сценарий. Я приветствую любую критику того, что я делаю неправильно с этим кодом; На самом деле, я умоляю вас, пожалуйста, высказать как можно больше критики в отношении моей техники, чтобы я мог извлечь из нее уроки.
Цели
Я установил новый пакет Zimbra Collaboration Suite для своей компании и в настоящее время занимаюсь миграцией учетных записей пользователей. Я пытаюсь создать скрипт bash, чтобы сделать следующее:
- Извлечь все учетные записи пользователей из активного каталога через LDAP.
- Отформатируйте результаты запроса LDAP для использования в
zmprov ca
команда. - Перечислите строки отформатированных результатов.
- Перебирайте каждую строку и запускайте ее как
zmprov
команда.
Предположения для целей этого примера
- Имя файла bash = zdap
- Мой домен Active Directory = MYLOCALDOMAIN
- Мое имя пользователя для LDAP = admin
- Мой пароль для LDAP = P@ssw0rd
- Мой LDAP IP-адрес = 1.2.3.4
скрипт
Вот мой сценарий:
#!/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
Я вызываю команду с этим:
./zdap local admin
Запрошено редактировать...zmprov
Команда для данного пользователя (Джо Смит) выглядит так:
zmprov ca joe.smith@mylocaldomain.com tempzimbrapw1234 sn 'Smith' gn 'Joe' displayName 'Joe Smith'
Результаты и моя проблема
- Запрос ldap выполняется отлично (например, если я выполню эту команду отдельно, он вернет правильные результаты ldap... поэтому проблема не связана с учетными данными LDAP / подключением / запросом).
- Если я повторяю команду, она также выглядит просто отлично (например, если я наберу команду в соответствии с отраженной версией, и она фактически добавит учетную запись, как я хочу).
Однако, когда я запускаю скрипт zdap bash, который я написал, я ожидаю получить подтверждение создания учетной записи от Zimbra, но вместо этого получу это сообщение:
zimbra@CPU-00154:~$ ./zdap local admin
usage: createAccount(ca) {name@domain} {password} [attr1 value1 [attr2 value2..
For general help, type : zmprov --help
К сожалению, я пробовал слишком много решений, чтобы перечислить их все здесь. Я потратил неделю на чтение руководств, форумов и т. Д. И перепробовал множество твиков, настроек, новых команд и т. Д., Но безрезультатно.
Еще раз, я был бы очень признателен за любую критику в отношении моего сценария или общего метода для достижения этой цели. Пожалуйста, попробуйте включить примеры с вашими предложениями, чтобы я мог видеть, что я делаю не так здесь. Заранее спасибо.
РЕДАКТИРОВАТЬ:
Я подумал, что должен включить формат результата запроса LDAP, чтобы вы могли увидеть, с чем работает моя команда:
dn: CN=admin,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: admin
mail: admin@mylocaldomain.com
--
dn: CN=Jane Doe,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: Jane Doe
mail: jane.doe@mylocaldomain.com
--
dn: CN=Joe Smith,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: Joe Smith
mail: joe.smith@mylocaldomain.com
ОБНОВИТЬ
Мне удалось решить проблему с помощью printf
команда (особая благодарность rici за это предложение). Вывод из printf был такой...
<|zmprov|> <|ca|> <|joe.smith@mylocaldomain.com|> <|tempzimbrapw1234|> <|#|> <|sn|> <|'Smith'|> <|gn|> <|'Joe'|> <|displayName|> <|'Joe|> <|Smith'|>
Как видите, значение последнего аргумента (displayName) было неверно истолковано.
1 ответ
Было бы полезно, если бы вы включили (2) в мой первый комментарий, особенно printf
версия:
printf '<|%s|> ' $line && printf '\n'
Тот printf
заявление поставит <|
|>
вокруг каждого аргумента, что позволяет увидеть разницу между:
<|zmprov|> <|ca|> ... <|displayName|> <|'Joe Smith'|>
а также
<|zmprov|> <|ca|> ... <|displayName|> <|'Joe|> <|Smith'|>
Но я рискну догадаться, что вы действительно хотите:
<|zmprov|> <|ca|> ... <|displayName|> <|Joe Smith|>
Цитирование сценариев оболочки занимает немного времени, чтобы разобраться. Такие инструменты, как этот оператор printf, помогут. Поэкспериментируйте немного с простыми командами. Обратите внимание на то, как раскрываются переменные. (И обратите внимание, что кавычки в значениях переменных - это просто обычные символы.) Также убедитесь, что вы понимаете разницу между zmprov $line
а также zmprov "$line"
,
Наконец, прочтите bash FAQ по цитированию: http://mywiki.wooledge.org/BashFAQ/050
Также, sed
может выполнить более одной команды за один вызов, и awk
может сделать большинство вещей sed
сможет сделать. Я подозреваю, что вы могли бы упростить эту массивную линию в простой awk
программа.