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.

tué
la source
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

Kent
la source
3
C'est ce que j'utilise. Voir superuser.com/questions/336275/find-out-if-user-name-exists
guettli
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.

poitroae
la source
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.

chepner
la source
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
Daniel Sokolowski
la source
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.

Valdas Rapševičius
la source
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
Takeda
la source
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.

Fleshgrinder
la source
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
Bakul Gupta
la source
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"
jackotonye
la source
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.

Christian Hujer
la source
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".

Yu Chai
la source
2

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

syam
la source
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
Steve
la source
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
Eugen Rieck
la source
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
Santosh Garole
la source
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
Luchaninov
la source
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
nir vizel
la source