Controlla se esiste un utente


165

Voglio creare uno script per verificare se esiste un utente. Sto usando la logica qui sotto:

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

Quindi se l'utente esiste, allora abbiamo successo, altrimenti l'utente non esiste. Ho messo sopra il comando nello script bash come di seguito:

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

Ora, il mio script dice sempre che l'utente esiste indipendentemente da cosa:

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

Perché la condizione precedente valuta sempre come VERA e dice che l'utente esiste?

Dove sto sbagliando?

AGGIORNARE:

Dopo aver letto tutte le risposte, ho riscontrato il problema nella mia sceneggiatura. Il problema era il modo in cui stavo reindirizzando l' getentoutput. Quindi ho rimosso tutte le cose di reindirizzamento e ho fatto getentapparire la linea in questo modo:

getent passwd $user  > /dev/null

Ora la mia sceneggiatura funziona bene.


Penso che quando usi $?ottieni il codice di ritorno del testcomando. Vedi la risposta sotto.
user000001,

È il codice esatto che stai eseguendo? Nessuna dichiarazione di debug "echo" tra la chiamata getente la tua ifdichiarazione? Ciò provocherebbe il $?controllo dello stato di uscita di echo, non la chiamata a getent.
Chepner,

4
Sì, penso che intendi 2>&1invece di 2&>1.
Tim Ludwinski,

Il codice funziona con input non vuoto, ma se $1non è impostato, l'istruzione if restituirà true. Dal mio test, la soluzione sarebbe quella di avvolgere $1tra virgolette: getent passwd "$1" > /dev/null 2&>1.
Vince,

Per favore, segna una risposta
Efren,

Risposte:


292

puoi anche controllare l'utente per idcomando.

id -u nameti dà l'id di quell'utente. se l'utente non esiste, hai il comando return value ( $?)1



24
ottima risposta - solo una piccola modifica che funziona bene ... user_exists = $ (id -u user> / dev / null 2> & 1; echo $?) user_exists = 0 se esiste "user", o 1 se no
Pancho

5
@Pancho Penso che la tua variabile dovrebbe essere chiamata user_doesnt_exist
Will Sheppard

1
@WillSheppard: A livello generale la gestione booleana in bash è secondo me meno che chiara e in genere evito deduzioni booleane implicite nel mio codice. Quanto segue rende la lettura interessante e, in modo interessante, entrambi favoriscono 0 = vero e <non 0> = falso per scopi bash e, sebbene non di fatto, allinearsi con il nome della variabile che ho usato anche da una prospettiva booleana: stackoverflow.com/a/5431932 / 3051627 . stackoverflow.com/questions/2933843/… .
Pancho,

2
Grazie al commento di @ Pancho ho potuto raggiungere questo obiettivo, semplicemente inviando l'errore nel vuoto e facendo validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }. Ciò restituisce praticamente 1 se l'utente esiste o 0 se non lo è.
lu1s

32

Perché non lo usi semplicemente

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

Restituirà 1 (poiché un utente ha un massimo di 1 voce) se l'utente esiste e 0 se non lo è.


19
Questo non funziona se il server utilizza un altro sistema per gestire usi come NIS o LDAP. In questo caso, puoi usaregetent passwd | grep -c '^username:'
Toby Jackson il

1
questo restituirà 1 se si dispone di un nome utente, diciamo "test1" e si desidera creare un nuovo nome utente chiamato "test".
Marin Nedea,

2
@MarinNedea i due punti :dopo il nome utente protegge dalla corrispondenza della sottostringa abbinandola al separatore di campo, quindi l'effetto che descrivi non accadrà.
Stéphane Gourichon,

30

Non è necessario controllare esplicitamente il codice di uscita. Provare

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

Se ciò non funziona, c'è qualcosa che non va nel tuo getent, o hai definito più utenti di quanto pensi.


23

Questo è quello che ho finito per fare in uno Freeswitchscript di avvio 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

Suggerisco di usare il comando id in quanto verifica l'esistenza di un utente valido e la voce del file passwd non necessaria significa lo stesso:

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

Nota: 0 è root uid.


12

Lo stavo usando in quel modo:

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

9

Di gran lunga la soluzione più semplice:

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

Si >/dev/null 2>&1può accorciare &>/dev/nullin Bash.


Si Grazie!
Zane Hitchcox, il

7

Script per verificare se l'utente Linux esiste o meno

Script Per verificare se l'utente esiste o meno

#! /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
Perché l'uso cat? grep $USER_NAME /etc/passwd >/dev/null 2>&1
Alexx Roche,

Sì Alexx Roche, non è necessario utilizzare cat, ne ho bisogno per avere un modo migliore di visualizzare il concetto per principianti.
Bakul Gupta,

6

Risposta in ritardo ma fingermostra anche ulteriori informazioni sull'utente

  sudo apt-get finger 
  finger "$username"

OP potrebbe non utilizzare Debian.
Narendra-Choudhary,

3

In realtà non riesco a riprodurre il problema. Lo script come scritto nella domanda funziona bene, tranne nel caso in cui $ 1 è vuoto.

Tuttavia, c'è un problema nello script relativo al reindirizzamento di stderr. Anche se le due forme &>ed >&esistono, nel tuo caso che si desidera utilizzare >&. Hai già reindirizzato stdout, ecco perché il modulo &>non funziona. Puoi verificarlo facilmente in questo modo:

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

Vedrai un file chiamato 1nella directory corrente. Si desidera utilizzare 2>&1invece o utilizzare questo:

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

Questo reindirizza anche stdoute stderral /dev/null.

Avviso Il reindirizzamento stderra /dev/nullpotrebbe non essere una buona idea. Quando le cose vanno male, non avrai idea del perché.


3

le informazioni dell'utente sono memorizzate in / etc / passwd, quindi puoi usare "grep 'nomeutente' / etc / passwd" per verificare se esiste il nome utente. nel frattempo puoi usare il comando shell "id", stamperà l'id utente e l'id gruppo, se l'utente non esiste, stamperà il messaggio "nessun tale utente".


2

Accedi al server. grep "nome utente" / etc / passwd Questo mostrerà i dettagli dell'utente se presenti.


3
Questo corrisponderà anche a qualsiasi nome utente che contenga "nome utente". Ad esempio "some_username". Ti piacerebbe fareif grep -q "^username:" /etc/passwd; then ...
maedox il

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

1

A seconda dell'implementazione della shell (ad es. Busybox o adulto) l' [operatore potrebbe avviare un processo, cambiando $?.

Provare

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

cambiare $?mi dà lo stesso risultato. Questa è la versione bash:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
slayedbylucifer,

Provaif test "$RES" == "0"; then ...
Eugen Rieck,

1
$?sarebbe espanso prima delle [esecuzioni, quindi non è un problema.
Chepner,

1
Invece di testare il risultato del comando, puoi testare direttamente il comando: 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

Di seguito è riportato lo script per controllare la distribuzione del sistema operativo e creare l'utente se non esiste e non fare nulla se l'utente esiste.

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

Crea un utente di sistema some_userse non esiste

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

0

Mi piace questa bella soluzione a una riga

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

e nello 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

uso:

[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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.