Πληροφορίες δικτύου

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 - αντικειμενοστρεφές περιτύλιγμα του οποίου οι μέθοδοι προσπέλασης απαλείφουν την ανάγκη να θυμάστε τη σειρά των πεδίων