ユーザーが提供する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
これを実行すると、ターミナルにプロンプトメッセージのみが表示され、機能しなくなります。
何か不足していますか?
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ベースのデータベースの場合のように)。
$ 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
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
ユーザーのユーザー名を出力するusers
とwho
もあります現在ログインしている現在のホストに。
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/passwd
、LDAP
、 NIS+
、...)見つかった最初のユーザーエントリ。 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は必要ありません。