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 getentperintah
Menggunakan getent passwdlebih portabel daripada penguraian /etc/passwdkarena ini juga menanyakan database NIS atau LDAP non-lokal.
getent passwd "$uid" | cut -d: -f1
Sayangnya, getentutilitas tersebut sepertinya tidak ditentukan oleh POSIX.
Gunakan idperintah
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?
getentatau tidak idakan mengembalikan apa pun melewati pertandingan pertama; satu-satunya cara untuk menemukan mereka semua adalah dengan menghitung semua pengguna, jika database pengguna mengizinkannya. (Mencari /etc/passwdkarya untuk pengguna yang ditentukan di sana, jelas.)
/etc/passwddan /etc/shadowuntuk menguji skenario ini dan memverifikasi bahwa keduanya iddan getent passwdberperilaku 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_iddapat 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 lsdigunakan untuk menerjemahkan UID ke nama masuk. Jawaban Gilles adalah cara yang lebih langsung dan efisien untuk mencapai ini.