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;
Τι επιστρέφεται#
Σε περιβάλλον λίστας - μια λίστα πέντε στοιχείων που αντιστοιχεί στο C struct hostent:
$name- το κανονικοποιημένο hostname για αυτή την εγγραφή.$aliases- συμβολοσειρά εναλλακτικών ονομάτων διαχωρισμένων με κενά.$addrtype- η οικογένεια διευθύνσεων, συνήθωςAF_INET(2) ήAF_INET6(10).$length- το μήκος σε bytes κάθε διεύθυνσης (4για IPv4,16για IPv6).@addrs- κάθε διεύθυνση που καταγράφεται για αυτόν τον υπολογιστή, καθεμία πακεταρισμένη δυαδική συμβολοσειρά$lengthbytes.
Στο τέλος της βάσης δεδομένων η επιστροφή είναι η κενή λίστα. Διάκριση που αξίζει να θυμάστε: η σημείωση του upstream perlfunc ότι μια εγγραφή που λείπει μπορεί να επιστρέψει «a single meaningless true value» αφορά τις αναζητήσεις κατά όνομα και κατά διεύθυνση, όχι την 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είναι επαναλήπτης βάσης δεδομένων, όχι περιτύλιγμα κλήσης συστήματος με την έννοια των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 - μέθοδοι προσπέλασης αντί για αποπακετάρισμα κατά θέση:
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))- ένα hostname"0"είναι θεωρητικά έγκυρο και θα τερμάτιζε ψευδώς έναν βρόχο βασισμένο σε αλήθεια.Ο
@addrsμπορεί να είναι κενός ακόμη και για επιστρεφόμενη εγγραφή σε ορισμένα NSS backends. Προστατέψτε το βήμα αποπακεταρίσματος διεύθυνσης:next unless @addrs;
Τα aliases είναι ένα βαθμωτό, όχι λίστα. Το
$aliasesείναι μία μεμονωμένη συμβολοσειρά διαχωρισμένη με κενά. Διασπάστε σε λευκούς χαρακτήρες αν θέλετε λίστα.Μείγμα πηγών NSS. Σε συστήματα βασισμένα σε glibc, η βάση δεδομένων hosts μπορεί να αντλεί από το
/etc/hosts, το DNS, το mDNS και άλλα αρθρώματα NSS ανάλογα με τοnsswitch.conf. Τα αρθρώματα NSS με backend DNS συνήθως δεν απαριθμούν - ηgethostentσε βάση δεδομένων hosts μόνο μέσω DNS επιστρέφει την κενή λίστα αμέσως. Στις περισσότερες πραγματικές αναπτύξεις μόνο η πηγήfilesσυνεισφέρει εγγραφές στην επανάληψη.Διαπλοκή με αναζητήσεις κατά όνομα / κατά διεύθυνση. Μια κλήση
gethostbynameήgethostbyaddrμπορεί να επαναφέρει τον κοινόχρηστο δρομέα. Ολοκληρώστε πρώτα την επανάληψη, ή επανεκκινήστε την μεsethostentμετά την αναζήτηση.Ασφάλεια threads. Η υποκείμενη ρουτίνα C διατηρεί στατική κατάσταση ανά διεργασία για τον δρομέα επανάληψης. Ταυτόχρονες κλήσεις από πολλαπλά threads διαπλέκουν τα αποτελέσματα απρόβλεπτα. Περιορίστε την απαρίθμηση σε ένα μόνο thread.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
sethostent- επαναφέρει τον επαναλήπτη και ελέγχει αν η βάση δεδομένων παραμένει ανοιχτή μεταξύ κλήσεωνendhostent- κλείνει τον επαναλήπτη και απελευθερώνει το handle της βάσης δεδομένωνgethostbyname- στοχευμένη αναζήτηση κατά όνομα αντί για πλήρη απαρίθμησηgethostbyaddr- στοχευμένη αντίστροφη αναζήτηση κατά πακεταρισμένη διεύθυνσηgetnetent- ίδιο μοτίβο επανάληψης για τη βάση δεδομένων δικτύωνSocket::inet_ntoa- μετατρέπει πακεταρισμένη διεύθυνση από τον@addrsσε συμβολοσειρά dotted-quad