getservent#
Διαβάζει την επόμενη εγγραφή από τη βάση δεδομένων υπηρεσιών του συστήματος.
Η getservent διασχίζει τη βάση δεδομένων /etc/services μία εγγραφή τη φορά, αποδίδοντας την ίδια λίστα πεδίων όπως οι getservbyname και getservbyport αλλά χωρίς κλειδί αναζήτησης. Κάθε κλήση προωθεί έναν εσωτερικό δρομέα· ο δρομέας ανοίγεται στην πρώτη κλήση, επαναφέρεται στην αρχή από την setservent και απελευθερώνεται από την endservent. Αντικατοπτρίζει τη ρουτίνα getservent(3) της C library του POSIX και κληρονομεί κάθε ιδιαιτερότητα φορητότητας που αυτό συνεπάγεται.
Σύνοψη#
my ($name, $aliases, $port, $proto) = getservent;
my $name = getservent; # scalar context
Τι επιστρέφεται#
Σε περιβάλλον λίστας, τέσσερα πεδία που ταιριάζουν με τη σειρά που τεκμηριώνεται για κάθε παραλλαγή getserv*:
$name- κανονικό όνομα υπηρεσίας, π.χ."http".$aliases- συμβολοσειρά εναλλακτικών ονομάτων διαχωρισμένων με κενά, π.χ."www www-http". Δεν είναι πίνακας· διασπάστε την εσείς αν χρειάζεστε πίνακα.$port- αριθμός θύρας ως εγγενής ακέραιος (σε σειρά bytes host), π.χ.80.$proto- πρωτόκολλο μεταφοράς, τυπικά"tcp"ή"udp".
Σε βαθμωτό περιβάλλον, μόνο το $name. Όταν ο δρομέας φτάσει στο τέλος αρχείου, η getservent επιστρέφει την κενή λίστα σε περιβάλλον λίστας και undef σε βαθμωτό περιβάλλον - ο ιδιωματικός βρόχος while (my @e = getservent) στηρίζεται σε αυτό.
Για να μετατρέψετε τα ψευδώνυμα σε λίστα:
my @alt = split / /, $aliases;
Καθολική κατάσταση που επηρεάζει#
Εσωτερικός δρομέας βάσης δεδομένων για το
/etc/services- μοιράζεται με τιςgetservbyname,getservbyport,setserventκαιendservent. Οποιαδήποτε αναζήτηση κατά όνομα ή κατά θύρα σε κάποιες πλατφόρμες επαναφέρει ή κλείνει αυτόν τον δρομέα ως παρενέργεια· επαναλάβετε σε σφιχτό βρόχο ή περιτυλίξτε την επανάληψη σεsetservent/endserventγια ασφάλεια.$!- τίθεται όταν η υποκείμενη κλήση C αναφέρει σφάλμα.Δεν είναι ασφαλής για threads. Η
getserventκρατάει κατάσταση ανά διεργασία, όχι ανά thread· δύο threads που επαναλαμβάνουν ταυτόχρονα θα αλληλομπλέξουν εγγραφές και κανένα δεν θα δει την πλήρη λίστα.
Παραδείγματα#
Διασχίστε ολόκληρη τη βάση δεδομένων υπηρεσιών και εκτυπώστε κάθε εγγραφή:
while (my ($name, $aliases, $port, $proto) = getservent) {
print "$name/$proto $port\n";
}
endservent;
Επαναφέρετε τον δρομέα πριν την επανάληψη ώστε προηγούμενες κλήσεις αλλού στο πρόγραμμα να μην τον αφήσουν στη μέση της ροής:
setservent(0);
while (my @e = getservent) {
# @e is ($name, $aliases, $port, $proto)
}
endservent;
Συλλέξτε μόνο υπηρεσίες TCP σε πίνακα κατακερματισμού με κλειδί τη θύρα:
my %tcp;
while (my ($name, undef, $port, $proto) = getservent) {
$tcp{$port} = $name if $proto eq 'tcp';
}
endservent;
Χρησιμοποιήστε την αντικειμενοστρεφή διεπαφή κατά όνομα από την Net::servent, η οποία παρακάμπτει την ενσωματωμένη και επιστρέφει blessed αντικείμενο με μεθόδους προσπέλασης:
use Net::servent;
while (my $s = getservent) {
printf "%-20s %5d/%s\n", $s->name, $s->port, $s->proto;
}
Οριακές περιπτώσεις#
Το τέλος αρχείου επιστρέφει κενό / undef, όχι σφάλμα. Μια ψευδής τιμή ενός βαθμωτού σε περιβάλλον λίστας (το
my @e = getserventδίνοντας κενή λίστα) είναι ο τερματιστής. Μην ελέγχετε την$!για να εντοπίσετε τέλος επανάληψης.Απόν
/etc/services: σε συστήματα χωρίς το αρχείο, η πρώτη κλήση επιστρέφει αμέσως την κενή λίστα και η$!τίθεται. Τίποτα στην κλήση δεν σηματοδοτεί τη διαφορά μεταξύ κενής και απούσας βάσης δεδομένων - επιθεωρήστε την$!πριν υποθέσετε ότι η βάση ήταν απλώς κενή.Διαμοιρασμός δρομέα με αναζητήσεις κατά όνομα / κατά θύρα: η κλήση
getservbynameήgetservbyportστη μέση ενός βρόχουgetserventμπορεί να επαναφέρει τον δρομέα σε κάποιες πλατφόρμες. Είτε ολοκληρώστε πρώτα τη διάσχιση είτε ξανανοίξτε μεsetservent.Το
$aliasesείναι συμβολοσειρά, όχι λίστα. Τοsplit / /, $aliasesσας δίνει τη μορφή πίνακα. Η άμεση αντιμετώπιση του$aliasesως λίστας σας δίνει σιωπηρά το μήκος λίστας ενός στοιχείου.Προγράμματα με threads: η επανάληψη είναι ανά διεργασία. Συντονίστε την πρόσβαση με κλείδωμα, ή προτιμήστε
getservbyname/getservbyportγια σημειακά ερωτήματα σε κώδικα με threads.Το βαθμωτό περιβάλλον επιστρέφει μόνο το όνομα. Αν χρειάζεστε τη θύρα, καλέστε σε περιβάλλον λίστας ακόμη και όταν ενδιαφέρεστε για ένα μόνο πεδίο.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
getservbyname- αναζητήστε μία μόνο υπηρεσία με το κειμενικό της όνομα αντί να επαναλαμβάνετεgetservbyport- αναζητήστε μία μόνο υπηρεσία με την αριθμητική της θύραsetservent- επαναφέρετε τον κοινό δρομέα πριν την επανάληψη ώστε προηγούμενες κλήσεις να μην τον αφήσουν στη μέση της ροήςendservent- απελευθερώστε τον δρομέα όταν η διάσχιση ολοκληρωθεί, ελευθερώνοντας τον υποκείμενο περιγραφέα αρχείουgetprotoent- ίδιο μοτίβο επαναλήπτη για το/etc/protocols, τυπικά συνδυάζεται όταν επιλύεται η πλειάδα(port, proto)Net::servent- αντικειμενοστρεφές περιτύλιγμα του οποίου οι μέθοδοι προσπέλασης απαλείφουν την ανάγκη να θυμάστε τη σειρά των πεδίων