0

さて、私は2 週間前にbashスクリプトを開始したばかりで、先週、修正できない問題に遭遇しました。私の問題をできる限り説明し、スクリプトを含めました。このコードの何が間違っているかについての批判を歓迎します。実際、私のテクニックについてできる限り多くの批判を提供していただき、そこから学ぶことができるようお願いします.


目的

会社用に新しいZimbra Collaboration Suiteをインストールし、ユーザー アカウントを移行中です。次のことを行う bash スクリプトを作成しようとしています。

  1. LDAP 経由で Active Directory からすべてのユーザー アカウントを取得します。
  2. コマンドで使用する LDAP クエリの結果をフォーマットしますzmprov ca
  3. 書式設定された結果の行を列挙します。
  4. 各行を繰り返し、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

Requested edit...特定のユーザー (Joe Smith) に対する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

残念ながら、ここにリストするにはあまりにも多くの解決策を試しました。マニュアルやフォーラムなどを読むのに 1 週​​間を費やし、大量の微調整、調整、新しいコマンドなどを試しましたが、役に立ちませんでした。

繰り返しますが、私のスクリプトまたはこれを達成するための全体的な方法に関する批判は大歓迎です。ここで何が間違っているかがわかるように、提案に例を含めてみてください。前もって感謝します。

編集:

私のコマンドが何を処理しているかを確認できるように、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) の値が誤って解釈されていました。

4

1 に答える 1

1

printf私の最初のコメント、特にバージョンから (2) を含めていただけると助かります。

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

また、sed1 回の呼び出しで複数のコマンドを実行でき、awkできることのほとんどをsed実行できます。その膨大な行を単純なawkプログラムに単純化できると思います。

于 2013-10-02T19:41:54.797 に答える