CentOSで冗長ユーザーを探す

CentOSで冗長ユーザーを探す

重複したユーザー名を見つけるには、次のコードを使用します。ただし、エラーが発生します。

#!/bin/bash
cat /etc/passwd | cut -f1 -d":" | /bin/sort -n | /usr/bin/uniq -c |\
    while read x; do [ -z "${x}" ] && break set - $x
        if [ $1 -gt 1 ]; then
            uids=`/bin/gawk -F: '($1 == n) { print $3 }' n=$2 \
            /etc/passwd | xargs`
            echo "Duplicate User Name ($2): ${uids}"
        fi
    done

「完了」マークの近くで構文エラーと数値エラーが発生します。このエラーをどのように解決できますか?

答え1

$ cut -d: -f1 /etc/passwd | sort | uniq -d

:これにより、区切られたファイル(ユーザー名)の最初のフィールドが抽出され、/etc/passwd結果がソートされ、重複項目が報告されます。

UIDと残りの重複passwdエントリの両方を取得します。

cut -d: -f1 /etc/passwd | sort | uniq -d |
while read -r username; do
  grep "^$username:" /etc/passwd
done

重複したユーザー名とそのUIDのみを取得します。

cut -d: -f1 /etc/passwd | sort | uniq -d |
while read -r username; do
  awk -F: -vu="$username" '$1 == u { print $1, $3 }' /etc/passwd
done

スクリプトに関する簡単なメモです。文法そうだほとんどはうまくいきますが、;後で必要であり、breakどちらも後ろにスペースがあります\(おそらく切り取りと貼り付けエラーでした(現在の編集で削除されています))。また、正当な理由なしに標準ユーティリティへのフルパスを提供するのを避け、awkプログラムにGNUが必要ないため、問題ありawkませんawk

答え2

  1. do通常、データを取得した後または確認した後の間に1つが必要です。whiledoneread
  2. set - $x1行に単独で入力するか、少なくともbreakセミコロン(;)で区切る必要があります。 (ここに置くのが良いようですdo。)

提案:

  1. そうするよりも変化をset - $x考慮してください。read xread count name
  2. 明確にするために、次のよう`…`に変更したい場合があります。$(…)これこれこれ

答え3

awk(1行)を使用して、次の操作を行います。

awk -F: '{if ($1 in users) print "Duplicate Username: "$1 ; else users[$1]}' /etc/passwd

ユーザー配列変数でユーザー名を探し、重複している場合はメッセージを印刷し、そうでない場合はユーザーを配列に追加します。

答え4

からインスピレーションを受けるエイバルの答え、このawkコマンドはOPスクリプトの意図された機能を複製します。

awk -F: '{ uids[$1] = uids[$1] " " $3; }
         END { for (u in uids) { if (uids[u] ~ /. /)
                         print "Duplicate User Name (" u "):" uids[u]; } }'

ebalの回答のように、一意のユーザー名ごとに1つの項目を含む連想配列を作成します。各行のスペースとユーザーのUIDを連結して、各項目の値を設定します。その後、ファイル全体を読み取った後で一意のユーザー名を繰り返して、そのユーザー名が複数回表示されることを確認し(UIDリストに最初の文字を除くスペースがあるという事実によって識別されます)、必要な情報を報告します。

ファイルのUIDにスペースが含まれていると、奇妙に動作する可能性があります。

関連情報