getpwuid#
מאתר את רשומת ה־passwd של משתמש לפי UID מספרי.
getpwuid עוטף את קריאת getpwuid(3) של ספריית ה־C של המערכת. העבירו מזהה משתמש מספרי כמו 0 או $<; תקבלו בחזרה את רשומת ה־passwd של אותו משתמש, או רשימה ריקה / undef אם UID כזה לא קיים. צורת ההחזרה תלויה בהקשר: הקשר רשימה נותן את כל שדות הרשומה; הקשר סקלרי נותן ערך שימושי אחד - עבור getpwuid ספציפית, שם ההתחברות.
תקציר#
getpwuid UID
מה מקבלים בחזרה#
הקשר רשימה מחזיר רשימה בת 10 אלמנטים המשקפת struct passwd מורחבת ב־BSD extras - אותה צורה ש־getpwnam מחזיר:
my ($name, $passwd, $uid, $gid, $quota,
$comment, $gcos, $dir, $shell, $expire) = getpwuid($uid);
$name- שם התחברות$passwd- סיסמה מוצפנת, או"x"/"*"במערכות shadow-password. מוכתם תחת-T.$uid- מזהה משתמש מספרי (אותו מספר שהעברתם)$gid- מזהה קבוצה ראשי מספרי$quota- מכסת דיסק, או$change/$ageבמערכות מסוימות. מחרוזת ריקה כשלא נתמך.$comment- הערה אדמיניסטרטיבית, לפעמים$class. מחרוזת ריקה כשלא נתמך.$gcos- שדה GECOS (בדרך כלל השם האמיתי בתוספת מידע משתמש אחר). מוכתם תחת-Tכי משתמשים יכולים לערוך אותו.$dir- ספריית הבית$shell- login shell. מוכתם תחת-T.$expire- תפוגת חשבון / סיסמה, כשנתמך.
הקשר סקלרי מחזיר רק את $name (שם ההתחברות). עבור getpwuid - איתור לפי UID - הקשר סקלרי נותן לכם ״את הדבר האחר״, תואם את הכלל שהמקור מתעד עבור כל הפונקציות getpw* / getgr* / gethost* / getnet* / getproto* / getserv*.
בכשל איתור שני ההקשרים מחזירים רשימה ריקה / undef. תמיד בדקו את ערך ההחזרה לפני פירוק.
מצב גלובלי שהוא נוגע בו#
קובע את
$!בכשל קריאת מערכת (נדיר - ״UID לא נמצא״ אינו כשל, זו החזרה ריקה).קורא את
$<ו־$>באופן מובלע רק כשמעבירים אותם, אך הניב הנפוץgetpwuid($<)הוא מה שהופך את משתנה ה־real-UID המיוחד לרשומה שימושית.תחת
-T(מצב taint),$passwd,$gcos, ו־$shellחוזרים מוכתמים. ראוperlsecכיצד לכבסם.חולק את אותו מצב איטרטור בסיסי עם
getpwent,setpwent, ו־endpwent. קריאתgetpwuidאינה מפריעה ללולאתgetpwentבעיצומה ב־glibc, אבל קוד נייד לא צריך להניח זאת.
דוגמאות#
איתור בסיסי UID־לשם בהקשר סקלרי:
my $name = getpwuid(0); # "root"
״תחת איזה משתמש אני רץ״ - הניב הקנוני של getpwuid, הפותר את ה־UID האמיתי לשם התחברות:
my $me = getpwuid($<); # e.g. "alice"
שלבו עם getlogin לקבלת שרשרת fallback אמינה השורדת תהליכים מנותקים ו־sessions של su:
my $login = getlogin() || getpwuid($<) || "unknown";
getlogin קורא את רשומת ה־tty השולטת ויכול לשקר (או להחזיר ריק) כשאין tty; getpwuid($<) עונה מה־UID הרשום של הקרנל ותמיד עובד.
רשומה מלאה בהקשר רשימה, עם בדיקה הגנתית:
my @pw = getpwuid($uid)
or die "uid $uid: not in passwd database";
my ($name, undef, undef, $gid, undef, undef, $gcos, $home, $shell) = @pw;
print "$name ($uid) -> $home, shell $shell\n";
מעבר UID → שם קבוצה דרך השדה $gid:
my $gid = (getpwuid($<))[3];
my $groupnam = getgrgid($gid);
גישה בסגנון עצם דרך הדריסה של User::pwent, שימושי כשרוצים accessors בעלי שם במקום לספור מיקומי רשימה:
use User::pwent;
my $pw = getpwuid($<);
printf "%s lives in %s, runs %s\n", $pw->name, $pw->dir, $pw->shell;
use User::pwent מחליף את getpwuid בגרסה המחזירה עצם ש־blessed עליו עם accessors ->name, ->uid, ->gid, ->dir, ->shell. שתי הצורות אינן מתערבבות: בתוך תחום אחד השתמשו או בדריסה או בפנימי, לא בשניהם.
מקרי קצה#
UID כזה לא קיים מחזיר רשימה ריקה בהקשר רשימה ו־
undefבהקשר סקלרי. זו אינה שגיאה -$!אינו נקבע. הבחינו בין ״UID חסר״ ל־״האיתור נכשל״ על־ידי בדיקת$!רק כשרוצים לדווח על כשל בלתי־צפוי, לא כשמחליטים האם ה־UID קיים.$passwdרק לעיתים רחוקות שימושי. במערכות Linux ו־BSD מודרניות ההאש האמיתי חי ב־/etc/shadow, קריא רק לשורש. תקבלו"x"או"*"כאן. השתמשו ב־PAM או במודולAuthen::PAMלאימות במקום להשוות מול שדה זה.ניידות
$quota,$comment,$expire. שדות אלה ריקים או חסרי משמעות ב־Linux. ה־POD של המקור מפרט ערכיConfig(d_pwquota,d_pwage,d_pwchange,d_pwcomment,d_pwexpire) שניתן לבדוק אם יש צורך לדעת בזמן ריצה האם הפלטפורמה מאכלסת אותם.שדות מוכתמים תחת
-T.$passwd,$gcos,$shellמוכתמים כי משתמשים יכולים לשנותם (דרךchsh,chfn, או עריכות ישירות של/etc/passwdבהקשרים מורשים). העבירו אותם דרך לכידת regex כדי לכבסם לפני שימוש בקריאת מערכת.החזרה סקלרית עבור UID 0 לעולם אינה שקר. בניגוד ל־
getpwnam, שהחזרתו הסקלרית עבורrootהיא ה־UID0(ערך שקר), ההחזרה הסקלרית שלgetpwuidהיא השם"root"- תמיד מחרוזת אמת עבור משתמשים קיימים.if (getpwuid($uid)) { ... }לכן עובד כמצופה, אבל פנו ל־definedבכל זאת אם אכפת לכם מההבחנה בין ״חסר״ ל־״שם ריק״:if (defined getpwuid($uid)) { ... } # unambiguous if (my @pw = getpwuid($uid)) { ... } # also correct
UID הוא מספר, לא שם.
getpwuid("root")ממיר את"root"ל־0(עם אזהרה תחתuse warnings) ומאתר UID0. השתמשו ב־getpwnamלאיתורים לפי שם.UIDs שליליים / חורגים בגודל. קריאת המערכת מקבלת כל מה ש־
uid_tמקבל על הפלטפורמה (בדרך כלל 32-bit unsigned). Perl ממיר ערכים שליליים דרך two’s-complement בכניסה; התוצאה ספציפית לפלטפורמה וכמעט לעולם לא מה שרוצים.ספריות גדולות (LDAP / NIS / SSSD).
getpwuidעובר דרך NSS, ולכן העלות מתאמת לאופן שבו ה־resolver המקומי עונה. החמצה מול שרת LDAP שמוגדר לא נכון יכולה לחסום למשך שניות. שמרו תוצאות ב־cache בהאש אם אתם פותרים UIDs רבים בלולאה צפופה (למשל בעת הוספת הערות לפלט בסגנוןls -l).Threads. המקור מציין ש־
getpwuid_rמשמש אוטומטית במקום שבו הפלטפורמה מספקת אותו; איטרצייתgetpwent, לעומת זאת, נשארת לכל־תהליך. לא מהווה דאגה תחת pperl (אין ithreads), אבל כדאי לדעת אם משתפים קוד עם perl5.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
getpwnam- אותה רשומה, מאותרת לפי שם התחברות; שלבו עםgetpwuidכשצריך לעבור שם → UIDgetpwent- איטרציה על מסד ה־passwd כולו; השתמשו כשצריך כל משתמש, לא ספציפיgetgrgid- מקבילה במסד הקבוצות; נדרש כדי לפתור את שדה ה־$gidמרשומה זו חזרה לשם קבוצהgetlogin- איתור זול של ״מי על ה־tty הזה״; חזרו אלgetpwuid($<)כשהוא מחזיר ריקUser::pwent- עוטף עצם עם accessors בעלי שם; פנו אליו כשרוצים->nameבמקום לספור מיקומי רשימה