ユーザーIDに関連付けられたログイン名を取得したいことがよくあります。これは一般的なユースケースであることが証明されているため、これを行うシェル関数を作成することにしました。私は主にGNU / Linuxディストリビューションを使用していますが、スクリプトをできるだけ移植性のあるものに書き、自分がやっていることがPOSIX互換であることを確認しようとしています。
解析 /etc/passwd
私が試みた最初のアプローチは、/etc/passwd
(を使用してawk
)解析することでした。
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
ただし、このアプローチの問題は、ログインがローカルではない可能性があることです。たとえば、ユーザー認証はNISまたはLDAPを介して行われる可能性があります。
getent
コマンドを使用する
を使用するgetent passwd
と、/etc/passwd
非ローカルのNISまたはLDAPデータベースも照会されるため、解析よりも移植性が高くなります。
getent passwd "$uid" | cut -d: -f1
残念ながら、getent
ユーティリティはPOSIXで指定されていないようです。
id
コマンドを使用する
id
ユーザーのIDに関するデータを取得するためのPOSIX標準化ユーティリティです。
BSDおよびGNU実装は、オペランドとしてユーザーIDを受け入れます。
これは、ユーザーIDに関連付けられたログイン名の印刷に使用できることを意味します。
id -nu "$uid"
ただし、オペランドとしてユーザーIDを指定することはPOSIXでは指定されていません。オペランドとしてのログイン名の使用についてのみ説明します。
上記のすべてを組み合わせる
上記の3つのアプローチを次のように組み合わせることを検討しました。
get_username(){
uid="$1"
# First try using getent
getent passwd "$uid" | cut -d: -f1 ||
# Next try using the UID as an operand to id.
id -nu "$uid" ||
# As a last resort, parse `/etc/passwd`.
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
}
ただし、これは不格好で洗練されておらず、さらに重要なことには堅牢ではありません。ユーザーIDが無効または存在しない場合、ゼロ以外のステータスで終了します。各コマンド呼び出しの終了ステータスを分析して保存する、より長くて不格好なシェルスクリプトを作成する前に、ここで質問したいと思いました。
ユーザーIDに関連付けられたログイン名を取得する、よりエレガントでポータブルな(POSIX互換の)方法はありますか?
getent
もid
返さないことです。それらすべてを見つける唯一の方法は、ユーザーデータベースで許可されている場合、すべてのユーザーを列挙することです。(/etc/passwd
明らかにそこに定義されているユーザーのための作品を探しています。)
/etc/passwd
し、/etc/shadow
このシナリオをテストするために、両方のことを検証id
し、getent passwd
あなたが説明するように動作します。ある段階で、ユーザーが複数の名前を持つシステムを使用することになった場合、これらのシステムユーティリティと同じことを行い、最初の出現をそのユーザーの正規名として単純に扱います。
setuid(some_id)
、some_id
ユーザーデータベースの一部である必要性はありません。Linuxのユーザー名前空間のようなものでは、これはあなたのスクリプトにとって重大な前提になるかもしれません。