web-dev-qa-db-ja.com

uidに基づいてユーザーの名前を表示する方法

ユーザーが提供するuidに基づいてユーザーの名前を表示するbashスクリプトを記述しようとしています。

#!/bin/bash

read -p "donner l UID" cheruid

 if [ $(grep -w $cheruid) -n ]
 then
    grep -w $cheruid /etc/passwd | cut -d ":" -f "1" | xargs echo "user is : "
else
    echo "user not found"

fi

これを実行すると、ターミナルにプロンプ​​トメッセージのみが表示され、機能しなくなります。

何か不足していますか?

4
mehdi zidani

GNU idを使用すると、次のことができます。

id -un -- "$cheruid"

これにより、アカウントデータベース(/etc/passwd、LDAP、NIS +、RDBMS ...に格納されているかどうか)に、そのuidを持つ最初のユーザー名を照会します。

通常、ユーザー名はuidごとに1つだけですが、保証はありません。ユーザーアカウントデータベースのキーは、ユーザーIDではなくユーザー名です。

特定のuidのすべてのユーザー名を知りたい場合は、次のようにします。

getent passwd | ID=$cheruid awk -F: '$3 == ENVIRON["ID"] {print $1}'

しかし、それは列挙可能でない一部のアカウントデータベースでは機能しない可能性があります(大規模なLDAPベースのデータベースの場合のように)。

12
$ printf 'User is %s\n' "$( getent passwd 1001 | cut -d : -f 1 )"
User is myself

(私のシステムにはUID 1001のmyselfユーザーがいます)

これはpasswdデータベースに特定のUIDを照会し、その応答からユーザー名を取り除き、その結果をprintfへの引数として使用します。これはmacOSでは機能しません。

不明なUIDをキャッチするには:

$ printf 'User is %s\n' "$( { getent passwd 1001 || echo 'UNKNOWN USER'; } | cut -d : -f 1 )"
User is myself
$ printf 'User is %s\n' "$( { getent passwd 1002 || echo 'UNKNOWN USER'; } | cut -d : -f 1 )"
User is UNKNOWN USER

コマンドラインで任意の数のUIDを取得するスクリプトとして(出力がわずかに変更されています):

#!/bin/sh

for uid do
    printf 'User with UID %d is %s\n' "$uid" \
        "$( { getent passwd "$uid" || echo 'NOT KNOWN'; } | cut -d : -f 1 )"
done

テスト(これは私のOpenBSDシステムでいくつかのサービスアカウントのUIDを通過します):

$ sh ./script.sh {110..115}
User with UID 110 is _sndiop
User with UID 111 is NOT KNOWN
User with UID 112 is _syspatch
User with UID 113 is NOT KNOWN
User with UID 114 is NOT KNOWN
User with UID 115 is _slaacd
5
Kusalananda

オリジナルのシェルスクリプトを手伝う

Ifステートメントのテストが問題の原因です。私は次のシェルスクリプトを提案します、

#!/bin/bash

read -p "donner l UID " cheruid

 if [ "$(grep -w "^$cheruid" /etc/passwd)" != "" ]
 then
    grep -w "$cheruid" /etc/passwd | cut -d ":" -f "1" | xargs echo "user is : "
else
    echo "user not found"
fi

Edit1:^をテストに追加して、行の先頭でのみ一致を検索しました。

Edit2::はセパレーターであるため、それとその後のすべてを削除し、テストで受け入れられた場合、結果をecho行で直接使用して、簡素化できます。シェルスクリプト

#!/bin/bash

read -p "donner l UID " cheruid

cheruid=${cheruid%%:*}
user=$(grep -wo "^$cheruid" /etc/passwd)

if [ "$user" != "" ]
then
    echo "user is : $user"
else
    echo "user not found"
fi

これは、優れたbashシェルスクリプトを作成するのに役立ちます。

idを使用してユーザーIDを見つける効率的でより一般的な方法

特定のユーザー名<test-name>が存在するかどうかを効率的に確認したい場合は、idを使用できます。これは、StéphaneChazelasの質問に対する別の回答で示されています。

id -un -- <test-name>

例えば

id -un -- mehdi

idは、/etc/passwdに保存されているユーザーIDだけでなく、他の方法で管理および保存されているユーザーIDも検出します。たとえば、Matteo Italiaがコメントしたプロのサーバーシステムで一般的なLDAPなどです。


すべてのユーザーをスキャンする場合

  • システムユーザー、ユーザー番号が1000未満の多くのLinuxシステム

  • 「ヒューマン」ユーザー、ユーザー番号が1000以上の多くのLinuxシステム

  • すべてのユーザーの数が2000未満であると仮定します(必要に応じて変更します)

次のbashワンライナーを使用できます。これはidでループを使用します。

for ((i=0;i<2000;i++));do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$i: $name" ;fi;done

「人間」のユーザーのみを表示し、ユーザーID番号がスキップされない(ユーザーが削除されていない)と想定する場合、次のbashワンライナーは非常に高速です。

i=1000;while true;do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$name" ;else break;fi;i=$((i+1));done

ただし、一部のID番号がスキップされる(ユーザーが削除される)と想定した方が信頼性が高くなります。

for ((i=1000;i<2000;i++));do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$i: $name" ;fi;done

ユーザーのユーザー名を出力するuserswhoもあります現在ログインしている現在のホストに。

4
sudodus

Grepを使用すると、任意の数が一致します。ユーザーIDまたはグループIDとして:

$ grep '109' /etc/passwd
uuidd:x:105:109::/run/uuidd:/bin/false
usbmux:x:109:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false

また、1109と一致する場合もあります。 grep -wとして呼び出された場合でも、1109との一致は回避されます。それは重要な問題です。


Getentを使用:

$ getent passwd 109
usbmux:x:109:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false

どちらが一致するかonlyアカウントデータベース(/etc/passwdLDAPNIS+、...)見つかった最初のユーザーエントリ。 macOSでは動作しません。

したがって、スクリプトは次のようになります。

#!/bin/bash
read -p "donner l UID: " cheruid

if     name=$(getent passwd "$cheruid")
then   name=${name%%:*}
       echo "user is : $name"
else   echo "user not found"
fi

名前を取得するためにsed、awk、cutは必要ありません。

0
Isaac