Vérifier si un utilisateur existe


165

Je souhaite créer un script pour vérifier si un utilisateur existe. J'utilise la logique ci-dessous:

# getent passwd test > /dev/null 2&>1
# echo $?
0
# getent passwd test1 > /dev/null 2&>1
# echo $?
2

Donc, si l'utilisateur existe, alors nous avons du succès, sinon l'utilisateur n'existe pas. J'ai mis la commande ci-dessus dans le script bash comme ci-dessous:

#!/bin/bash

getent passwd $1 > /dev/null 2&>1

if [ $? -eq 0 ]; then
    echo "yes the user exists"
else
    echo "No, the user does not exist"
fi

Maintenant, mon script dit toujours que l'utilisateur existe quoi qu'il arrive:

# sh passwd.sh test
yes the user exists
# sh passwd.sh test1
yes the user exists
# sh passwd.sh test2
yes the user exists

Pourquoi la condition ci-dessus évalue-t-elle toujours VRAI et indique-t-elle que l'utilisateur existe?

Où vais-je mal?

METTRE À JOUR:

Après avoir lu toutes les réponses, j'ai trouvé le problème dans mon script. Le problème était la façon dont je redirigeais la getentsortie. J'ai donc supprimé tous les éléments de redirection et j'ai fait getentressembler la ligne à ceci:

getent passwd $user  > /dev/null

Maintenant, mon script fonctionne correctement.


Je pense que lorsque vous utilisez, $?vous obtenez le code retour de la testcommande. Voir la réponse ci-dessous.
user000001

Est-ce le code exact que vous exécutez? Aucune instruction de débogage «écho» entre l'appel à getentet votre ifinstruction? Cela entraînerait la $?vérification de l'état de sortie de echo, pas de votre appel à getent.
chepner

4
Ouais, je pense que tu veux dire 2>&1au lieu de 2&>1.
Tim Ludwinski

Le code fonctionne sur une entrée non vide, mais si $1n'est pas défini, l'instruction if retournera true. De mes tests, la solution serait d'envelopper $1dans des guillemets doubles: getent passwd "$1" > /dev/null 2&>1.
Vince

Veuillez marquer une réponse
Efren

Réponses:


292

vous pouvez également vérifier l'utilisateur par idcommande.

id -u namevous donne l'identifiant de cet utilisateur. si l'utilisateur n'existe pas, vous avez la valeur de retour de la commande ( $?)1



24
excellente réponse - juste une modification mineure qui fonctionne bien ... user_exists = $ (id -u user> / dev / null 2> & 1; echo $?) user_exists = 0 si "user" existe, ou 1 sinon
Pancho

5
@Pancho Je pense que votre variable devrait être nommée user_doesnt_exist
Will Sheppard

1
@WillSheppard: Au niveau général, la gestion des booléens dans bash est à mon avis moins que claire et j'évite généralement les inférences booléennes implicites dans mon code. Ce qui suit rend la lecture intéressante et, de manière intéressante, favorise à la fois 0 = true et <not 0> = false à des fins de bash, et bien que ce ne soit pas de facto, alignez-vous avec le nom de variable que j'ai utilisé dans une perspective booléenne également: stackoverflow.com/a/5431932 / 3051627 . stackoverflow.com/questions/2933843/… .
Pancho

2
Grâce au commentaire de @ Pancho, j'ai pu y parvenir, simplement en envoyant l'erreur dans le vide et en faisant validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }. Cela renvoie à peu près 1 si l'utilisateur existe, ou 0 s'il n'existe pas.
lu1s

32

Pourquoi n'utilisez-vous pas simplement

grep -c '^username:' /etc/passwd

Il renverra 1 (car un utilisateur a au maximum 1 entrée) si l'utilisateur existe et 0 dans le cas contraire.


19
Cela ne fonctionne pas si le serveur utilise un autre système pour gérer les utilisations telles que NIS ou LDAP. Dans ce cas, vous pouvez utilisergetent passwd | grep -c '^username:'
Toby Jackson

1
ceci retournera 1 si vous avez un nom d'utilisateur, disons "test1" et que vous voulez créer un nouveau nom d'utilisateur appelé "test".
Marin Nedea

2
@MarinNedea le deux-points :après le nom d'utilisateur protège contre la correspondance de sous-chaîne en faisant correspondre le séparateur de champ, de sorte que l'effet que vous décrivez ne se produira pas.
Stéphane Gourichon

30

Il n'est pas nécessaire de vérifier explicitement le code de sortie. Essayer

if getent passwd $1 > /dev/null 2>&1; then
    echo "yes the user exists"
else
    echo "No, the user does not exist"
fi

Si cela ne fonctionne pas, il y a un problème avec votre getent, ou vous avez défini plus d'utilisateurs que vous ne le pensez.


23

C'est ce que j'ai fini par faire dans un Freeswitchscript de démarrage bash:

# Check if user exists
if ! id -u $FS_USER > /dev/null 2>&1; then
    echo "The user does not exist; execute below commands to crate and try again:"
    echo "  root@sh1:~# adduser --home /usr/local/freeswitch/ --shell /bin/false --no-create-home --ingroup daemon --disabled-password --disabled-login $FS_USER"
    echo "  ..."
    echo "  root@sh1:~# chown freeswitch:daemon /usr/local/freeswitch/ -R"
    exit 1
fi

14

Je suggère d'utiliser la commande id car elle teste l'existence d' un utilisateur valide avec l'entrée de fichier passwd qui n'est pas nécessaire signifie la même chose:

if [ `id -u $USER_TO_CHECK 2>/dev/null || echo -1` -ge 0 ]; then 
echo FOUND
fi

Remarque: 0 est l'uid racine.


12

Je l'utilisais de cette façon:

if [ $(getent passwd $user) ] ; then
        echo user $user exists
else
        echo user $user doesn\'t exists
fi

9

De loin la solution la plus simple:

if id -u user >/dev/null 2>&1; then
    echo user exists
else
    echo user missing
fi

Le >/dev/null 2>&1peut être raccourci en &>/dev/nulldans Bash.


Oui merci!
Zane Hitchcox

7

Script pour vérifier si l'utilisateur Linux existe ou non

Script Pour vérifier si l'utilisateur existe ou non

#! /bin/bash
USER_NAME=bakul
cat /etc/passwd | grep ${USER_NAME} >/dev/null 2>&1
if [ $? -eq 0 ] ; then
    echo "User Exists"
else
    echo "User Not Found"
fi

2
Pourquoi utiliser cat? grep $USER_NAME /etc/passwd >/dev/null 2>&1
Alexx Roche

Oui Alexx Roche, il n'y a pas besoin d'utiliser chat, je l'ai utilisé afin d'avoir une meilleure façon de visualiser le concept pour débutant.
Bakul Gupta

6

Réponse tardive mais fingeraffiche également plus d'informations sur l'utilisateur

  sudo apt-get finger 
  finger "$username"

OP n'utilise peut-être pas Debian.
narendra-choudhary

3

En fait, je ne peux pas reproduire le problème. Le script tel qu'écrit dans la question fonctionne correctement, sauf dans le cas où $ 1 est vide.

Cependant, il existe un problème dans le script lié à la redirection de stderr. Bien que les deux formes &>et >&existent, dans votre cas, vous souhaitez utiliser >&. Vous avez déjà redirigé stdout, c'est pourquoi le formulaire &>ne fonctionne pas. Vous pouvez facilement le vérifier de cette façon:

getent /etc/passwd username >/dev/null 2&>1
ls

Vous verrez un fichier nommé 1dans le répertoire courant. Vous souhaitez utiliser à la 2>&1place, ou utilisez ceci:

getent /etc/passwd username &>/dev/null

Cela redirige également stdoutet stderrvers /dev/null.

Avertissement La redirection stderrvers /dev/nulln'est peut-être pas une si bonne idée. Lorsque les choses tournent mal, vous ne saurez pas pourquoi.


3

les informations sur l'utilisateur sont stockées dans / etc / passwd, vous pouvez donc utiliser "grep 'usename' / etc / passwd" pour vérifier si le nom d'utilisateur existe. en attendant, vous pouvez utiliser la commande shell "id", elle affichera l'identifiant de l'utilisateur et l'identifiant du groupe, si l'utilisateur n'existe pas, elle affichera le message "aucun utilisateur de ce type".


2

Connectez-vous au serveur. grep "username" / etc / passwd Ceci affichera les détails de l'utilisateur s'il est présent.


3
Cela correspondra également à tout nom d'utilisateur contenant "username". Par exemple, "un_nom_utilisateur". Vous voudriez faireif grep -q "^username:" /etc/passwd; then ...
maedox

2

Utilisation de sed:

username="alice"
if [ `sed -n "/^$username/p" /etc/passwd` ]
then
    echo "User [$username] already exists"
else
    echo "User [$username] doesn't exist"
fi

1

En fonction de votre implémentation shell (par exemple Busybox vs adulte), l' [opérateur peut démarrer un processus, en changeant $?.

Essayer

getent passwd $1 > /dev/null 2&>1
RES=$?

if [ $RES -eq 0 ]; then
    echo "yes the user exists"
else
    echo "No, the user does not exist"
fi

le changement $?me donne le même résultat. Ceci est la version bash:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
slayedbylucifer

Essayezif test "$RES" == "0"; then ...
Eugen Rieck

1
$?serait développé avant l' [exécution, ce n'est donc pas un problème.
chepner le

1
Au lieu de tester le résultat de la commande, vous pouvez tester la commande directement: if getent passwd $1 > /dev/null 2&>1; then echo "yes the user exists" else echo "No, the user does not exist" fi
GMartinez

1

Vous trouverez ci-dessous le script pour vérifier la distribution du système d'exploitation et créer un utilisateur s'il n'existe pas et ne rien faire si l'utilisateur existe.

#!/bin/bash

# Detecting OS Ditribution
if [ -f /etc/os-release ]; then
    . /etc/os-release
    OS=$NAME
elif type lsb_release >/dev/null 2>&1; then
OS=$(lsb_release -si)
elif [ -f /etc/lsb-release ]; then
    . /etc/lsb-release
    OS=$DISTRIB_ID
else
    OS=$(uname -s)
fi

 echo "$OS"

 user=$(cat /etc/passwd | egrep -e ansible | awk -F ":" '{ print $1}')

 #Adding User based on The OS Distribution
 if [[ $OS = *"Red Hat"* ]] || [[ $OS = *"Amazon Linux"* ]] || [[ $OS = *"CentOS"*  
]] && [[ "$user" != "ansible" ]];then
 sudo useradd ansible

elif [ "$OS" =  Ubuntu ] && [ "$user" != "ansible" ]; then
sudo adduser --disabled-password --gecos "" ansible
else
  echo "$user is already exist on $OS"
 exit
fi

0

Créer un utilisateur système some_users'il n'existe pas

if [[ $(getent passwd some_user) = "" ]]; then
    sudo adduser --no-create-home --force-badname --disabled-login --disabled-password --system some_user
fi

0

J'aime cette belle solution en une ligne

getent passwd username > /dev/null 2&>1 && echo yes || echo no

et en script:

#!/bin/bash

if [ "$1" != "" ]; then
        getent passwd $1 > /dev/null 2&>1 && (echo yes; exit 0) || (echo no; exit 2)
else
        echo "missing username"
        exit -1
fi

utilisation:

[mrfish@yoda ~]$ ./u_exists.sh root
yes
[mrfish@yoda ~]$ echo $?
0

[mrfish@yoda ~]$ ./u_exists.sh
missing username
[mrfish@yoda ~]$ echo $?
255

[mrfish@yoda ~]$ ./u_exists.sh aaa
no
[mrfish@indegy ~]$ echo $?
2
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.