gethostent#
מחזיר את הרשומה הבאה ממסד נתוני המארחים.
gethostent walks the host database - on traditional Unix systems the /etc/hosts file, on modern systems whatever NSS source is configured
returning one record per call until the database is exhausted. Use it when you want to enumerate every known host, not when you want to resolve a single name:
gethostbynameis the right tool for a targeted lookup.
סמן האיטרציה משותף עם sethostent (שמחזיר אותו לאחור) ועם endhostent (שסוגר אותו). בין שתי הקריאות הללו gethostent מחזיר כל רשומה בסדר, ואז מחזיר את הרשימה הריקה (או undef בהקשר סקלר) ברגע שמגיעים לסוף מסד הנתונים.
תקציר#
my ($name, $aliases, $addrtype, $length, @addrs) = gethostent;
my $name = gethostent;
מה מקבלים בחזרה#
הקשר רשימה - רשימה בת חמישה אלמנטים המשקפת את ה־struct hostent של C:
$name- שם המארח הקנוני לרשומה זו.$aliases- מחרוזת שמות חלופיים מופרדים ברווח.$addrtype- משפחת הכתובות, בדרך כללAF_INET(2) אוAF_INET6(10).$length- אורך כל כתובת בבתים (4עבור IPv4,16עבור IPv6).@addrs- כל כתובת שנרשמה עבור המארח הזה, כל אחת מחרוזת בינארית ארוזה של$lengthבתים.
בסוף מסד הנתונים ההחזרה היא רשימה ריקה. הבחנה שכדאי לזכור: ההערה ב־perlfunc של upstream שרשומה חסרה עשויה להחזיר ״ערך אמת בודד וחסר משמעות״ חלה על חיפושים לפי שם ולפי כתובת, לא על gethostent - איטרציה מעבר לסוף היא רשימה ריקה נקייה.
הקשר סקלר - רק ה־$name הקנוני, או undef בסוף מסד הנתונים. השתמשו בהקשר רשימה בכל פעם שאתם צריכים משהו מעבר לשם; שחזור השדות האחרים אינו אפשרי בדיעבד.
המירו כתובת ארוזה מתוך @addrs באמצעות Socket::inet_ntoa עבור IPv4 או באמצעות unpack ישירות:
use Socket;
print inet_ntoa($addrs[0]), "\n";
מצב גלובלי שהוא נוגע בו#
סמן מסד נתוני המארחים, משותף עם
sethostent,endhostent,gethostbyname, ו־gethostbyaddr. חיפוש לפי שם או לפי כתובת עלול לאפס או לבטל סמן שהושאר באמצע איטרציה על־ידיgethostent; אל תשלבו בין שני הסגנונות ללאsethostentחדש ביניהם.$?- נקבע לערךh_errnoשל C במקרה של כשל, היכן שהפלטפורמה חושפת אותו. סוף־מסד־נתונים רגיל אינו כשל ומותיר את$?ללא שינוי.$!-gethostentהוא איטרטור על מסד נתונים, לא עטיפת syscall במובן שלopen/read. שגיאות DNS ו־NSS צפות דרךh_errno(דרך$?), לא דרך$!.
דוגמאות#
מנו כל מארח במסד הנתונים:
use Socket;
sethostent(1);
while (my ($name, $aliases, $type, $len, @addrs) = gethostent) {
my @dotted = map { inet_ntoa($_) } @addrs;
print "$name @dotted\n";
}
endhostent;
הקשר סקלר - רשמו רק את השמות הקנוניים:
sethostent(0);
while (defined(my $name = gethostent)) {
print "$name\n";
}
endhostent;
בנו האש של שם־לכתובת במעבר אחד, ואז חפשו רשומות מקומית ללא קריאות DNS נוספות:
use Socket;
my %ip_of;
sethostent(1);
while (my ($name, $aliases, undef, undef, @addrs) = gethostent) {
next unless @addrs;
$ip_of{$name} = inet_ntoa($addrs[0]);
$ip_of{$_} = inet_ntoa($addrs[0]) for split ' ', $aliases;
}
endhostent;
print $ip_of{"localhost"} // "not in hosts DB", "\n";
ממשק לפי־רשומה דרך עקיפת Net::hostent - מתודות accessor במקום פירוק מיקומי:
use Net::hostent;
while (my $h = gethostent) {
printf "%-30s %s\n", $h->name, join(",", @{$h->aliases});
}
מקרי קצה#
אין הפניה לאחור משתמעת.
gethostentאינו פותח או מחזיר לאחור את מסד הנתונים בעצמו. הקריאה הראשונה לאחר תחילת התוכנית עובדת מפני שספריית C פותחת את מסד הנתונים בעצלתיים, אך ברגע שמגיעים לסוף, קריאות נוספות ממשיכות להחזיר סוף־מסד־נתונים עד ש־sethostentמחזיר את הסמן לאחור. תמיד צמדו מנייה ל־sethostent/endhostentמפורשים.ארגומנט
STAYOPENל־sethostent. העברת ערך אמת מבקשת מהספרייה להשאיר את קובץ מסד הנתונים פתוח לאורך החיפושים, מה שחשוב למקורות NSS שאחרת היו מתחברים מחדש בכל קריאה. העברת0מתירה לספרייה לסגור ולפתוח מחדש בין קריאות.סוף־מסד־נתונים הוא רשימה ריקה, לא
undef. בהקשר רשימה תנאי הלולאהwhile (my @r = gethostent)עובד מפני שרשימה ריקה היא שקר. בהקשר סקלר השתמשו ב־while (defined(my $name = gethostent))- שם מארח"0"תקף תיאורטית והיה מסיים שגויות לולאה מבוססת־אמיתיות.@addrsעלול להיות ריק גם עבור רשומה שמוחזרת בחלק מ־backends של NSS. הגנו על שלב פירוק־הכתובת:next unless @addrs;
הכינויים הם סקלר אחד, לא רשימה.
$aliasesהוא מחרוזת בודדה מופרדת ברווח. פצלו על רווח לבן אם רוצים רשימה.ערבוב מקורות NSS. במערכות מבוססות glibc מסד נתוני המארחים עשוי לשאוב מ־
/etc/hosts, DNS, mDNS, ומודולי NSS אחרים, בהתאם ל־nsswitch.conf. מודולי NSS מבוססי־DNS בדרך־כלל אינם מבצעים מנייה -gethostentכנגד מסד נתוני מארחים מבוסס־DNS בלבד מחזיר את הרשימה הריקה מיידית. ברוב הפריסות האמיתיות רק מקורfilesתורם רשומות לאיטרציה.שילוב עם חיפושים לפי שם / לפי כתובת. קריאה ל־
gethostbynameאו ל־gethostbyaddrיכולה לאפס את הסמן המשותף. סיימו את האיטרציה תחילה, או הפעילו אותה מחדש עםsethostentלאחר החיפוש.בטיחות thread. רוטינת ה־C הבסיסית שומרת מצב סטטי לכל־תהליך עבור סמן האיטרציה. קריאות בו־זמניות ממספר threads משלבות תוצאות באופן בלתי־צפוי. הגבילו את המנייה ל־thread יחיד.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
sethostent- מחזיר את האיטרטור לאחור ושולט האם מסד הנתונים נשאר פתוח לאורך הקריאותendhostent- סוגר את האיטרטור ומשחרר את ה־handle של מסד הנתוניםgethostbyname- חיפוש ממוקד לפי שם במקום מנייה מלאהgethostbyaddr- חיפוש הפוך ממוקד לפי כתובת ארוזהgetnetent- אותה תבנית איטרציה עבור מסד נתוני הרשתותSocket::inet_ntoa- הופך כתובת ארוזה מתוך@addrsלמחרוזת dotted-quad