Πληροφορίες χρηστών και ομάδων

endgrent#

Κλείνει τη βάση δεδομένων ομάδων μετά την επανάληψη πάνω της.

Η endgrent είναι το μισό του καθαρισμού της τριάδας επανάληψης βάσης ομάδων setgrent / getgrent / endgrent. Λέει στην C library ότι έχετε τελειώσει τη διάσχιση του /etc/group (ή της πηγής NSS πίσω από αυτό), απελευθερώνοντας όποιους περιγραφείς αρχείων ή ενταμιευμένη κατάσταση άνοιξε η βιβλιοθήκη για λογαριασμό σας. Μετά την endgrent, η επόμενη κλήση getgrent ξεκινά φρέσκια επανάληψη από την κορυφή.

Σύνοψη#

endgrent;
endgrent();

Χωρίς ορίσματα, χωρίς ουσιαστική τιμή επιστροφής.

Τι επιστρέφεται#

Η τιμή επιστροφής είναι απροσδιόριστη και δεν πρέπει να βασίζεστε σε αυτήν. Η endgrent καλείται για την παρενέργειά της - το κλείσιμο της βάσης ομάδων - όχι για αποτέλεσμα. Θεωρήστε την ως κλήση σε κενό περιβάλλον.

endgrent;                           # correct
my $ok = endgrent;                  # wrong: $ok is not a success flag

Αν η πλατφόρμα σας δεν υλοποιεί την endgrent, η κλήση εγείρει croak με The endgrent function is unimplemented κατά τον χρόνο εκτέλεσης. Αυτός είναι ουσιαστικά έλεγχος που γίνεται μία φορά - αν η συνάρτηση δουλεύει στο σύστημά σας έστω και μία φορά, θα συνεχίσει να δουλεύει.

Καθολική κατάσταση που επηρεάζει#

Η endgrent λειτουργεί αμιγώς στην εσωτερική κατάσταση επανάληψης ομάδων της libc που μοιράζονται οι setgrent και getgrent. Δεν διαβάζει ούτε γράφει καμία ειδική μεταβλητή της Perl. Δεν αλλάζει το $!: μια διαδρομή αποτυχίας που θέτει το errno στην υποκείμενη κλήση C δεν αναδύεται στην Perl.

The iteration state is per-process, not per-thread. In a threaded program, one thread’s endgrent closes the iteration for every thread

  • see Edge cases.

Παραδείγματα#

Το κανονικό μοτίβο επανάληψης-και-κλεισίματος. Πάντα ζευγαρώνετε έναν βρόχο setgrent / getgrent με endgrent ώστε προγράμματα που τρέχουν για πολύ ώρα να μη διαρρέουν τον περιγραφέα αρχείου που κρατά ανοιχτό η C library:

setgrent;
while (my @g = getgrent) {
    my ($name, $passwd, $gid, $members) = @g;
    print "$name ($gid): $members\n";
}
endgrent;

Το να μπείτε σε endgrent στη μέση της επανάληψης είναι νόμιμο - απλώς εγκαταλείπει όποια θέση δρομέα κρατούσε η βιβλιοθήκη:

setgrent;
while (my @g = getgrent) {
    last if $g[0] eq 'wheel';       # found what we wanted
}
endgrent;                           # release the handle anyway

Επανεκκίνηση της επανάληψης. Η endgrent ακολουθούμενη από setgrent είναι ο φορητός τρόπος για επαναφορά στην αρχή:

setgrent;
my @first_pass  = collect_groups();
endgrent;

setgrent;
my @second_pass = collect_groups();  # starts over from the top
endgrent;

Αμυντικός καθαρισμός σε μπλοκ END για προγράμματα που μπορεί να πεθάνουν στη μέση της διάσχισης:

setgrent;
END { endgrent }
while (my @g = getgrent) { ... }    # any die still triggers END

Οριακές περιπτώσεις#

  • Η κλήση της endgrent χωρίς προηγούμενη setgrent ή getgrent είναι αβλαβής. Η C library σιωπηρά δεν κάνει τίποτα αν δεν είναι σε εξέλιξη επανάληψη.

  • Η κλήση της δύο φορές διαδοχικά είναι επίσης αβλαβής - η δεύτερη κλήση είναι no-op.

  • Αμφισημία του αναλυτή. Η endgrent δεν δέχεται όρισμα και έχει την προτεραιότητα ονομασμένου μοναδιαίου τελεστή. Μια bareword έκφραση αμέσως στα δεξιά της θα αναλυθεί ως όρισμα και θα απορριφθεί:

    endgrent or die;                  # WRONG: parses as endgrent(or die)
    endgrent() or die;                # right: empty parens disambiguate
    

    Στην πράξη δεν υπάρχει τίποτα με το οποίο να ελέγξετε την τιμή επιστροφής, οπότε αυτή η παγίδα σπάνια δαγκώνει - αλλά ο ίδιος κανόνας ισχύει για κάθε αλυσιδωτή έκφραση.

  • Τα threads μοιράζονται την επανάληψη. Η endgrent από ένα thread τερματίζει την επανάληψη για όλα τα threads της ίδιας διεργασίας, επειδή η υποκείμενη κατάσταση είναι καθολική σε επίπεδο διεργασίας. Μην διαπλέκετε κλήσεις getgrent μεταξύ threads περιμένοντας ότι κάθε ένα θα δει κάθε εγγραφή.

  • NSS και caching. Σε συστήματα όπου η βάση δεδομένων ομάδων εξυπηρετείται μέσω NSS (nss_ldap, nss_sss, κ.λπ.), η endgrent απελευθερώνει caches ανά module που μπορεί να κρατά το backend NSS. Μακρόβιοι δαίμονες που διασχίζουν περιοδικά τη βάση δεδομένων ομάδων θα πρέπει να καλούν endgrent μετά από κάθε διάσχιση ώστε να αποφεύγεται η συσσώρευση κατάστασης backend.

  • Δεν επηρεάζει τις κλήσεις αναζήτησης βάσει ονόματος. Οι getgrnam και getgrgid είναι ανεξάρτητες του δρομέα επανάληψης. Η endgrent δεν ακυρώνει τα αποτελέσματά τους ούτε τα ενταμιευμένα δεδομένα τους, και δεν χρειάζεται να καλείτε endgrent πριν ή μετά από αυτές.

  • Μη υλοποιημένη σε ορισμένες πλατφόρμες. Η Perl εγείρει croak The endgrent function is unimplemented αν η libc του υπολογιστή δεν έχει endgrent(3). Όλα τα σύγχρονα συστήματα Linux, BSD και macOS την παρέχουν.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • setgrent - ανοίγει ή επαναφέρει τη βάση δεδομένων ομάδων πριν τη διάσχισή της· πάντα ο πρόλογος επανάληψης που τερματίζει με endgrent

  • getgrent - ανακτά την επόμενη εγγραφή από την επανάληψη που κλείνει η endgrent

  • getgrnam - αναζήτηση μίας ομάδας με βάση το όνομα, ανεξάρτητη από τον δρομέα επανάληψης· δεν χρειάζεται endgrent

  • getgrgid - ίδια με την getgrnam αλλά με κλειδί αριθμητικό gid

  • endpwent - η παράλληλη κλήση καθαρισμού για τη βάση δεδομένων passwd· οι δύο επαναλήψεις είναι ανεξάρτητες και και οι δύο χρειάζονται κλείσιμο αν ανοίξατε και τις δύο