web-dev-qa-db-ja.com

グループ番号(GID)をパラメーターとして受け入れるスクリプトを作成します

グループ番号(GID)をパラメーターとして受け入れるスクリプトを作成しようとしています。パラメータは任意の数にすることができます。スクリプトのタスクは、(/etc/passwdファイルに基づいて)指定されたグループに属するユーザーの数を計算して表示することです。スクリプトはawkコマンドを使用できません。

今のところ書いた

#!/bin/bash 
cat /etc/passwd 
test(){
local dir gid name pass Shell uid user
while IFS=':' read user pass uid gid name dir Shell ;do
}

そして、私は次が何であるかわかりませんか?

1
Johny N

すべてのグループはgroupデータベースにあります。グループのメンバーの数を数えるには、メンバーを抽出し、それらの間のコンマを数えます。グループメンバーの数は、1プラスこの数です。

#!/bin/sh

n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

printf 'There are %d members of group %s\n' "$(( n + 1 ))" "$1"

このアプローチの欠点は、グループが無効であっても、出力として常に少なくとも1つのメンバーを取得することです。ただし、最初に有効なグループをテストできます。

#!/bin/sh

if ! getent group "$1" >/dev/null; then
    printf 'No such group: %s\n' "$1" >&2
    exit 1
fi

n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )

printf 'There are %d members of group %s\n' "$(( n + 1 ))" "$1"

スクリプトは、最初のコマンドライン引数として数値のGIDとグループ名の両方を受け入れます。

awkを使用すると、代わりに

n=$( getent group "$1" | awk -F : '{ print split($4,dummy,",") }' )

後で$nに1を追加しないか、単に

getent group "$1" | awk -F : '
    { 
        printf("There are %d members of group %s (%d)\n",
            split($4,dummy,","), $1, $3)
    }'

(シェル)printfまたはn変数なし。

これは、groupデータベースに記録されているグループメンバーシップをカウントします。 primaryグループメンバーシップのみをカウントするには、次のようなものを使用します

n=$( getent passwd | cut -d : -f 4 | grep -cxF "$1" )

ただし、最初に$1が実際に有効なグループIDであることを確認することをお勧めします。

両方プライマリグループメンバーシップと補足グループメンバーシップをカウントするには、すべてのユーザーをループして、それぞれにidを使用するのが最適な場合があります。

getent passwd | cut -d : -f 1 |
while read user; do
    if id -G "$user" | tr ' ' '\n' | grep -q -xF "$1"; then
        n=$(( n + 1 ))
    fi
done

これにより、すべてのユーザー名が抽出され、それぞれでid -Gが呼び出され、結果のGIDのリストが改行で区切られたリストに変換されます。次に、grepは、指定されたGIDがそのリストの一部であるかどうかを判別し、含まれている場合は、nが1つインクリメントされます。

またはより速く、しかし醜い、

n=$( getent passwd | cut -d : -f 1 |
     while read user; do
         id -G "$user"
     done | tr ' ' '\n' | grep -c -xF "$1" )

あるいは、

n=$( getent passwd    | cut -d : -f 1 |
     xargs -n 1 id -G | tr ' ' '\n'   |
     grep -c -xF "$1" )

これが適切なアプローチである理由は、プライマリグループがgroupデータベースに自分自身を含まないユーザーがいる可能性があるためです。

1
Kusalananda