Compruebe si existe un usuario

165

Quiero crear un script para verificar si existe un usuario. Estoy usando la lógica a continuación:

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

Entonces, si el usuario existe, entonces tenemos éxito, de lo contrario, el usuario no existe. He puesto el comando anterior en el script bash como se muestra a continuación:

#!/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

Ahora, mi script siempre dice que el usuario existe sin importar qué:

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

¿Por qué la condición anterior siempre se evalúa como VERDADERA y dice que el usuario existe?

¿A dónde me estoy yendo mal?

ACTUALIZAR:

Después de leer todas las respuestas, encontré el problema en mi script. El problema era la forma en que estaba redirigiendo la getentsalida. Así que eliminé todas las cosas de redirección e hice que la getentlínea se viera así:

getent passwd $user  > /dev/null

Ahora mi script está funcionando bien.

slayedbylucifer
fuente
Creo que cuando lo $?usas obtienes el código de retorno del testcomando. Ver la respuesta a continuación.
user000001
¿Es ese el código exacto que está ejecutando? ¿No hay declaraciones de depuración "echo" entre la llamada getenty su ifdeclaración? Eso haría $?que verifique el estado de salida de echo, no su llamada a getent.
chepner
44
Sí, creo que te refieres en 2>&1lugar de 2&>1.
Tim Ludwinski
El código funciona en entradas no vacías, pero si $1no se establece, la instrucción if devolverá verdadero. De mis pruebas, la solución sería para envolver $1entre comillas dobles: getent passwd "$1" > /dev/null 2&>1.
Vince
Por favor marque una respuesta
Efren

Respuestas:

292

También puede verificar el usuario por idcomando.

id -u namete da la identificación de ese usuario. si el usuario no existe, obtiene el valor de retorno del comando ( $?)1

Kent
fuente
24
gran respuesta: solo un pequeño cambio que funciona bien ... user_exists = $ (id -u user> / dev / null 2> & 1; echo $?) user_exists = 0 si "user" existe, o 1 si no es así
Pancho
55
@Pancho Creo que tu variable debería llamarse user_doesnt_exist
Will Sheppard
1
@WillSheppard: En un nivel general, el manejo booleano en bash es, en mi opinión, poco claro y, por lo general, evito inferencias booleanas implícitas en mi código. Lo siguiente es una lectura interesante e interesantemente ambos favorecen 0 = verdadero y <no 0> = falso para bash, y aunque no de facto, se alinean con el nombre de la variable que he usado también desde una perspectiva booleana: stackoverflow.com/a/5431932 / 3051627 . stackoverflow.com/questions/2933843/… .
Pancho
2
Gracias al comentario de @ Pancho pude lograr eso, simplemente enviando el error al vacío y haciendo validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }. Eso, más o menos devuelve 1 si el usuario existe, o 0 si no existe.
lu1s
32

¿Por qué no simplemente usas

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

Devolverá 1 (ya que un usuario tiene un máximo de 1 entrada) si el usuario existe y 0 si no existe.

poitroae
fuente
19
Esto no funciona si el servidor está utilizando otro sistema para administrar usos como NIS o LDAP. En este caso, puede usargetent passwd | grep -c '^username:'
Toby Jackson
1
esto devolverá 1 si tiene un nombre de usuario, digamos "prueba1" y desea crear un nuevo nombre de usuario llamado "prueba".
Marin Nedea
2
@MarinNedea los dos puntos :después del nombre de usuario protegen contra la coincidencia de subcadenas haciendo coincidir con el separador de campo, por lo que el efecto que describas no sucederá.
Stéphane Gourichon
30

No hay necesidad de verificar el código de salida explícitamente. Tratar

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

Si eso no funciona, hay algo mal con usted getento tiene más usuarios definidos de lo que cree.

chepner
fuente
23

Esto es lo que terminé haciendo en un Freeswitchscript de inicio 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
fuente
14

Sugiero usar el comando id, ya que prueba la existencia válida del usuario wrt passwd entrada de archivo que no es necesariamente significa lo mismo:

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

Nota: 0 es root uid.

Valdas Rapševičius
fuente
12

Lo estaba usando de esa manera:

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

Con mucho, la solución más simple:

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

El >/dev/null 2>&1puede ser acortado &>/dev/nullen Bash.

Grillete de carne
fuente
¡Si, gracias!
Zane Hitchcox
7

Script para verificar si el usuario de Linux existe o no

Script Para verificar si el usuario existe o no

#! /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
fuente
2
¿Por qué usar cat? grep $USER_NAME /etc/passwd >/dev/null 2>&1
Alexx Roche
Sí Alexx Roche, no hay necesidad de usar cat, lo he usado para tener una mejor manera de visualizar el concepto para principiantes.
Bakul Gupta
6

Respuesta tardía pero fingertambién muestra más información sobre el usuario

  sudo apt-get finger 
  finger "$username"
jackotonye
fuente
OP podría no estar usando Debian.
narendra-choudhary
3

En realidad no puedo reproducir el problema. El script tal como está escrito en la pregunta funciona bien, excepto en el caso de que $ 1 esté vacío.

Sin embargo, hay un problema en el script relacionado con la redirección de stderr. Aunque existen las dos formas &>y >&existen, en su caso desea utilizarlas >&. Ya redirigió stdout, por eso el formulario &>no funciona. Puede verificarlo fácilmente de esta manera:

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

Verá un archivo nombrado 1en el directorio actual. Desea usar 2>&1en su lugar, o use esto:

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

Esto también redirige stdouty stderrhacia /dev/null.

Advertencia Redireccionar stderra /dev/nullpodría no ser una buena idea. Cuando las cosas van mal, no tendrás idea de por qué.

Christian Hujer
fuente
3

la información del usuario se almacena en / etc / passwd, por lo que puede usar "grep 'usename' / etc / passwd" para verificar si existe el nombre de usuario. mientras tanto, puede usar el comando de shell "id", imprimirá el id del usuario y el id del grupo, si el usuario no existe, imprimirá el mensaje "no existe ese usuario".

Yu Chai
fuente
2

Inicie sesión en el servidor. grep "nombre de usuario" / etc / passwd Esto mostrará los detalles del usuario si están presentes.

syam
fuente
3
Esto también coincidirá con cualquier nombre de usuario que contenga "nombre de usuario". Por ejemplo, "some_username". Te gustaría hacerif grep -q "^username:" /etc/passwd; then ...
maedox
2

Usando 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
fuente
1

Dependiendo de su implementación de shell (por ejemplo, Busybox vs. adulto), el [operador puede comenzar un proceso, cambiando $?.

Tratar

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
fuente
El cambio $?me da la misma salida. Esta es la versión bash:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
slayedbylucifer
Pruebaif test "$RES" == "0"; then ...
Eugen Rieck
1
$?se expandiría antes de las [ejecuciones, por lo que no es un problema.
chepner
1
En lugar de probar el resultado del comando, puede probar el comando directamente: 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

A continuación se muestra el script para verificar la distribución del sistema operativo y crear un usuario si no existe y no hacer nada si el usuario 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
fuente
0

Crear usuario del sistema some_usersi no existe

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

Me gusta esta buena solución de una línea

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

y 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

utilizar:

[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
fuente