web-dev-qa-db-fra.com

Lister tous les utilisateurs humains

Comment puis-je lister tous les utilisateurs humains que j'ai créés? J'ai essayé cat /etc/passwd et il énumère simplement beaucoup de choses.

19
anatoly techtonik

Les utilisateurs humains ont des UID commençant à 1000, vous pouvez donc utiliser ce fait pour filtrer les non-humains:

cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1

Ceci coupe le premier (nom d'utilisateur) et le troisième (UID) champs délimités par des deux-points dans /etc/passwd, filtre ensuite les lignes résultantes qui se terminent par un signe deux-points et quatre chiffres, puis coupe le premier champ (nom d'utilisateur), vous laissant ainsi une liste. d’utilisateurs dont l’ID utilisateur est compris entre 1000 et 9999.

Si vous avez plus de neuf mille utilisateurs sur votre système, cela échouera - mais il est nécessaire de limiter le résultat à des UID à 4 chiffres afin de ne pas intercepter nobody(UID 65534).

18
user132994

Cela fait à peu près ce que la réponse acceptée fait, en une seule commande au lieu de trois:

awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd

Et grâce à Karel dans les commentaires, l’utilisateur nobody est également filtré.

15
Oli

Personnellement, j'aime utiliser seulement:

ls /home

Certes, il ne s'agit pas d'une liste d'utilisateurs, mais d'une liste de leurs répertoires personnels. Les utilisateurs humains existants sur le système auront des répertoires de base dans /home, mais vous pourrez également voir les répertoires de base des anciens utilisateurs qui ont été supprimés.

Cela fonctionne pour mes besoins et peut également fonctionner pour le vôtre. Par exemple, si vous souhaitez supprimer un compte d'utilisateur qui n'existe plus (nonexistent-user), exécutez la commande.

Sudo deluser nonexistent-user

il vous dira simplement que cet utilisateur n'existe pas.

7
Sam Hamblin

Bien que cela puisse sembler une idée claire, il existe en réalité une ambiguïté dans la signification de utilisateur humain . Un compte d'utilisateur est-il délibérément masqué de l'écran de connexion parce qu'il est utilisé uniquement à des fins spécialisées (mais par des humains) en tant qu'utilisateur humain? Qu'en est-il de l'utilisateur ubuntu (UID 999) sur le CD en direct? Et les comptes d’invités dans Ubuntu sont créés à la volée et détruits après la déconnexion; sont-ils des utilisateurs humains? Plus d'exemples pourraient être conçus.

Par conséquent, il convient que plusieurs réponses non équivalentes aient été données. La solution de Saige Hamblin d'exécuter ls /home correspond à ce que font réellement les gens et, à moins d'écrire un script, vous devriez probablement vous en servir.

Rendre ls /home plus robuste

Mais vous avez peut-être des utilisateurs qui ont été supprimés, mais dont les répertoires personnels existent toujours dans /home, et vous devez éviter de les lister. Ou peut-être pour une autre raison, vous devez vous assurer que seules les entrées de /home qui correspondent à des comptes réels sont répertoriées.

Dans ce cas, je suggère de passer les noms de tout dans /home à getent (pour récupérer les entrées passwd des utilisateurs portant ces noms), puis isoler et afficher uniquement le champ nom d'utilisateur (avec grep , sed , ou awk , selon vos préférences). N'importe lequel d'entre eux fera:

getent passwd $(ls /home) | grep -o '^[^:]*'
getent passwd $(ls /home) | sed 's/:.*//'
getent passwd $(ls /home) | awk -F: '{print $1}'

Cela devrait bien fonctionner, car vous ne devriez pas avoir de comptes utilisateur avec des espaces ou des caractères de contrôle dans leurs noms; ne peut pas, sans reconfigurer Ubuntu pour l'autoriser ; et si vous le faites, vous avez de plus gros problèmes. Donc les problèmes habituels avec l'analyse ls sont ​​inapplicable. Mais même si c'est vraiment correct ici, si vous envisagez des substitutions de commandes avec ls déplaisant esthétiquement ou juste une mauvaise habitude, vous préférerez peut-être:

getent passwd $(basename -a /home/*) | grep -o '^[^:]*'
getent passwd $(basename -a /home/*) | sed 's/:.*//'
getent passwd $(basename -a /home/*) | awk -F: '{print $1}'

Ceux-ci n'acceptent pas les espaces ni les caractères de contrôle. Je ne les fournis que parce que $(ls /home) ne semble pas correct même s’il est correct, et frotte donc de nombreux utilisateurs dans le mauvais sens. Dans la plupart des situations, il existe de bonnes et vraies raisons d'éviter l'analyse ls , et dans ces situations, l'analyse basename -a n'est généralement que très légèrement moins mauvaise. Dans cette situation, cependant, en raison de la limitation des caractères pouvant apparaître dans les noms d'utilisateurs , ils conviennent tous les deux.

Explication, avantages et inconvénients

J'utilise getent principalement parce qu'il accepte les noms d'utilisateurs comme arguments pour limiter sa sortie, mais aussi parce qu'il est légèrement plus universel que d'examiner directement /etc/passwd, dans le cas où les fonctions d'authentification et la base de données de mots de passe sont fournies par des services réseau.

Cette méthode présente l’avantage supplémentaire par rapport à ls /home que, sur les systèmes dotés d’une partition /home distincte, lost+found apparaît généralement dans le résultat de ls /home.

  • Avec la méthode plus robuste présentée ci-dessus, lost+found n'apparaîtra que s'il existe un utilisateur (humain ou non) appelé lost+found, ce qui est peu probable.
  • Mais si vous entrez des commandes de manière interactive plutôt que d'écrire un script, ls /home est correct - , vous savez que vous n'avez pas d'utilisateur humain appelé lost+found.

Rarement, cette méthode (dans l’une des variantes ci-dessus) produira un résultat insatisfaisant:

  • Si le répertoire de base d'un utilisateur existe en dehors de /home, ou pas du tout, cela suggère mais n'implique pas que le compte ne doit pas être considéré comme représentant un utilisateur humain. Cette méthode répertorie uniquement les utilisateurs lorsqu'il existe un répertoire du même nom dans /home.
  • Si vous avez créé dans /home des répertoires supplémentaires qui ne sont en réalité pas le répertoire personnel de personne, et , ils portent le même nom qu'un utilisateur non humain existant - ou sont constitués de mots. séparés par des espaces, dont un ou plusieurs porte le même nom qu'un utilisateur non humain existant - certains utilisateurs non humains peuvent alors être inclus dans la sortie.
    (Cette méthode peut être implémentée avec une boucle et des invocations getent distinctes, donc le fractionnement des mots ne produit pas de sortie parasite. Mais la complexité n'est pas garantie; fondamentalement, si vous utilisez /home autrement que comme lieu. pour les répertoires personnels des utilisateurs, cette méthode ne produira pas de sortie fiable.)

Rendre la vérification UID plus simple

Si vous décidez d'utiliser une méthode qui vérifie les ID utilisateur pour vous assurer qu'ils se trouvent dans la plage probable des comptes représentant des êtres humains, comme dans la réponse acceptée ou la réponse de Oli , alors Je suggère ceci pour la brièveté:

getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'

Ceci utilise un expression régulière Perl (-P) pour afficher:

  • texte au début d'une ligne (^) ne contenant pas :s ([^:]+) - il s'agit du premier champ, car : est le séparateur de champs dans passwd
  • qui précède mais n'inclut pas ((?=)) le champ de mot de passe x - il devrait toujours être x, car dans Ubuntu, les hachages de mots de passe sont stockés dans la base de données shadow , et non dans la base de données lisible par le monde passwd
  • et un champ UID composé d’exactement 4 chiffres (:\d{4}:).

Il s’agit donc d’une variante nettement plus courte et un peu plus simple de la technique dans le réponse acceptée . (La technique décrite ici fonctionne également très bien et offre l’avantage d’être portable sur des systèmes non-GNU/Linux dont grep ne supporte pas -P.)

Reconsidérer la plage d'UID "humaine"

Si vous souhaitez gérer des UID très élevés et rechercher explicitement nobody, vous pouvez utiliser la méthode suivante Oli's answer . Cependant, vous voudrez peut-être déterminer si les utilisateurs avec des UID très élevés doivent réellement être considérés comme des utilisateurs ou s'ils sont plus susceptibles d'être utilisés par un autre utilisateur non humain à des fins spécifiques (comme nobody). Dans la pratique, de tels utilisateurs - en plus de nobody-- - sont rares, alors c’est vraiment une décision de votre part.

Un compromis possible consiste à répertorier les utilisateurs dans la plage des UID actuellement attribués à des utilisateurs non "nouvellement créés". Vous pouvez vérifier ceci in adduser.conf :

$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999

Voici deux manières de répertorier les utilisateurs dont les UID vont de 1000 à 29999:

getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'
4
Eliah Kagan

TL; DR: seuls les utilisateurs humains ont SystemAccount = false

Une autre méthode consiste à répertorier la sortie de tout en ignorant la racine ls /var/lib/AccountsService/users/ | grep -v root. Maintenant, il y a un excentrique - gdm, un écran de greeter/login (ou plus officiellement, le gestionnaire de bureau) est également répertorié en tant qu'utilisateur. Donc, juste à partir de la liste, nous ne pouvons pas dire si GDM est humain ou non.

Une approche plus efficace et correcte consiste à parcourir les fichiers de ce dossier et à identifier les utilisateurs répertoriés comme ayant SystemAccount=false. Le soufflet à une doublure réalise que

grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'

1

Sur les systèmes Buntu, les utilisateurs habituels (utilisateurs humains, par exemple) ont des UID commençant par 1 000, qui leur sont attribués de manière séquentielle lors de la création de leurs comptes. Tout cela revient à dire que le premier compte créé sur un système Buntu a un UID de 1000. Le prochain compte créé a un UID de 1001. Et ainsi de suite.

Ainsi, le moyen le plus simple de répertorier tous les comptes d'utilisateurs humains présents sur le système consiste, à mon avis, à vérifier si la troisième colonne du fichier /etc/passwd qui contient l'UID de l'utilisateur est supérieure ou égale à 1 000 et inférieure à, disons, 2000 (il est très peu probable qu'un PC de bureau classique ait plus d'un millier de comptes d'utilisateurs, vous ne pensez pas?):

$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
1
misha

En rejoignant la partie, je supervise des systèmes réseau utilisant LDAP, avec des répertoires de départ en dehors de /home et des UID (dus à un problème de script) par millions. Aucune des réponses actuelles ne fonctionne donc. Le test qui fonctionne pour moi consiste à vérifier si l'utilisateur dispose d'un shell de connexion valide. Un shell valide est celui qui est répertorié dans /etc/shells . La forme la plus simple:

getent passwd | grep -wFf /etc/shells

Le fichier peut contenir des commentaires (ou des lignes vides), il peut donc être nécessaire de les filtrer:

getent passwd | grep -wFf <(grep '^/' /etc/shells)
1
muru