Saya sering ingin mendapatkan nama login yang dikaitkan dengan ID pengguna dan karena itu terbukti menjadi kasus penggunaan umum, saya memutuskan untuk menulis fungsi shell untuk melakukan ini. Walaupun saya terutama menggunakan distribusi GNU / Linux, saya mencoba untuk menulis skrip saya agar se portable mungkin dan untuk memeriksa bahwa apa yang saya lakukan kompatibel dengan POSIX.
Parse /etc/passwd
Pendekatan pertama yang saya coba adalah mengurai /etc/passwd
(menggunakan awk
).
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
Namun, masalah dengan pendekatan ini adalah bahwa login mungkin tidak bersifat lokal, mis. Otentikasi pengguna bisa melalui NIS atau LDAP.
Gunakan getent
perintah
Menggunakan getent passwd
lebih portabel daripada penguraian /etc/passwd
karena ini juga menanyakan database NIS atau LDAP non-lokal.
getent passwd "$uid" | cut -d: -f1
Sayangnya, getent
utilitas tersebut sepertinya tidak ditentukan oleh POSIX.
Gunakan id
perintah
id
adalah utilitas standar POSIX untuk mendapatkan data tentang identitas pengguna.
Implementasi BSD dan GNU menerima ID Pengguna sebagai operan:
Ini berarti dapat digunakan untuk mencetak nama login yang terkait dengan ID Pengguna:
id -nu "$uid"
Namun, memberikan ID Pengguna karena operan tidak ditentukan dalam POSIX; itu hanya menggambarkan penggunaan nama login sebagai operan.
Menggabungkan semua hal di atas
Saya mempertimbangkan untuk menggabungkan ketiga pendekatan di atas menjadi sesuatu seperti berikut:
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
}
Namun, ini kikuk, tidak elegan dan - lebih penting - tidak kuat; keluar dengan status tidak nol jika ID Pengguna tidak valid atau tidak ada. Sebelum saya menulis skrip shell yang lebih panjang dan clunkier yang menganalisis dan menyimpan status keluar dari setiap permintaan perintah, saya pikir saya akan bertanya di sini:
Apakah ada cara yang lebih elegan dan portabel (kompatibel dengan POSIX) untuk mendapatkan nama login yang dikaitkan dengan ID pengguna?
getent
atau tidak id
akan mengembalikan apa pun melewati pertandingan pertama; satu-satunya cara untuk menemukan mereka semua adalah dengan menghitung semua pengguna, jika database pengguna mengizinkannya. (Mencari /etc/passwd
karya untuk pengguna yang ditentukan di sana, jelas.)
/etc/passwd
dan /etc/shadow
untuk menguji skenario ini dan memverifikasi bahwa keduanya id
dan getent passwd
berperilaku seperti yang Anda jelaskan. Jika, pada tahap tertentu, saya akhirnya menggunakan sistem di mana pengguna memiliki beberapa nama, saya akan melakukan hal yang sama seperti utilitas sistem ini dan hanya memperlakukan kejadian pertama sebagai nama kanonik untuk pengguna itu.
setuid(some_id)
, dan tidak ada persyaratan yang some_id
dapat menjadi bagian dari basis data pengguna apa pun. Dengan hal-hal seperti ruang nama pengguna di Linux, ini bisa berubah menjadi asumsi yang melumpuhkan untuk skrip Anda.
getpwuid()
fungsi yang ls
digunakan untuk menerjemahkan UID ke nama masuk. Jawaban Gilles adalah cara yang lebih langsung dan efisien untuk mencapai ini.