Überprüfen Sie, ob ein Benutzer vorhanden ist

164

Ich möchte ein Skript erstellen, um zu überprüfen, ob ein Benutzer vorhanden ist. Ich verwende die folgende Logik:

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

Wenn der Benutzer existiert, haben wir Erfolg, sonst existiert der Benutzer nicht. Ich habe den obigen Befehl wie folgt in das Bash-Skript eingefügt:

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

Jetzt sagt mein Skript immer, dass der Benutzer existiert, egal was passiert:

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

Warum wird die obige Bedingung immer als WAHR bewertet und es wird angegeben, dass der Benutzer vorhanden ist?

Wo gehe ich falsch?

AKTUALISIEREN:

Nachdem ich alle Antworten gelesen hatte, fand ich das Problem in meinem Skript. Das Problem war die Art und Weise, wie ich die getentAusgabe umleitete . Also habe ich alles Umleitungsmaterial entfernt und die getentZeile so aussehen lassen:

getent passwd $user  > /dev/null

Jetzt funktioniert mein Skript einwandfrei.

Slayedbylucifer
quelle
Ich denke, wenn Sie verwenden, erhalten $?Sie den Rückkehrcode des testBefehls. Siehe Antwort unten.
user000001
Ist das der genaue Code, den Sie ausführen? Keine "Echo" -Debug-Anweisungen zwischen dem Aufruf von getentund Ihrer ifAnweisung? Dies würde dazu führen $?, dass der Exit-Status von echound nicht Ihr Anruf bei überprüft wird getent.
Chepper
4
Ja, ich denke du meinst 2>&1statt 2&>1.
Tim Ludwinski
Code funktioniert bei nicht leeren Eingaben, aber wenn $1nicht festgelegt, gibt die if-Anweisung true zurück. Nach meinen Tests wäre die Lösung, $1in doppelte Anführungszeichen zu setzen : getent passwd "$1" > /dev/null 2&>1.
Vince
Bitte markieren Sie eine Antwort
Efren

Antworten:

292

Sie können den Benutzer auch per idBefehl überprüfen .

id -u namegibt Ihnen die ID dieses Benutzers. Wenn der Benutzer nicht existiert, erhalten Sie den Befehl return value ( $?)1

Kent
quelle
24
gute Antwort - nur eine kleine Änderung, die gut funktioniert ... user_exists = $ (id -u Benutzer> / dev / null 2> & 1; echo $?) user_exists = 0 wenn "Benutzer" existiert, oder 1 wenn nicht
Pancho
5
@Pancho Ich denke, Ihre Variable sollte user_doesnt_exist heißen
Will Sheppard
1
@ WillSheppard: Auf einer allgemeinen Ebene ist die boolesche Behandlung in Bash meiner Meinung nach nicht klar und ich vermeide normalerweise implizite boolesche Schlussfolgerungen in meinem Code. Das Folgende ist interessant zu lesen und bevorzugt interessanterweise sowohl 0 = wahr als auch <nicht 0> = falsch für Bash-Zwecke und stimmt, obwohl nicht de facto, mit dem Variablennamen überein, den ich auch aus boolescher Sicht verwendet habe: stackoverflow.com/a/5431932 / 3051627 . stackoverflow.com/questions/2933843/… .
Pancho
2
Dank des Kommentars von @ Pancho konnte ich dies erreichen, indem ich den Fehler einfach ins Leere schickte und es tat validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }. Das gibt so ziemlich 1 zurück, wenn ein Benutzer vorhanden ist, oder 0, wenn dies nicht der Fall ist.
lu1s
31

Warum benutzt du nicht einfach

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

Es wird 1 zurückgegeben (da ein Benutzer maximal 1 Eintrag hat), wenn der Benutzer existiert, und 0, wenn dies nicht der Fall ist.

Poitroae
quelle
19
Dies funktioniert nicht, wenn der Server ein anderes System zum Verwalten von Anwendungen wie NIS oder LDAP verwendet. In diesem Fall können Siegetent passwd | grep -c '^username:'
Toby Jackson
1
Dies gibt 1 zurück, wenn Sie einen Benutzernamen haben, sagen wir "test1" und möchten einen neuen Benutzernamen namens "test" erstellen.
Marin Nedea
2
@MarinNedea Der Doppelpunkt :nach dem Benutzernamen schützt vor Übereinstimmungen mit Teilzeichenfolgen, indem er mit dem Feldtrennzeichen übereinstimmt, sodass der von Ihnen beschriebene Effekt nicht auftritt.
Stéphane Gourichon
30

Der Exit-Code muss nicht explizit überprüft werden. Versuchen

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

Wenn das nicht funktioniert, stimmt etwas nicht mit Ihrem getentoder Sie haben mehr Benutzer definiert als Sie denken.

chepner
quelle
23

Folgendes habe ich in einem FreeswitchBash-Startskript getan :

# 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
quelle
14

Ich schlage vor, den Befehl id zu verwenden, da er die gültige Benutzerexistenz für den Eintrag in einer passwd-Datei testet, was nicht erforderlich ist. Dies bedeutet dasselbe:

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

Hinweis: 0 ist Root-UID.

Valdas Rapševičius
quelle
12

Ich habe es so benutzt:

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

Mit Abstand die einfachste Lösung:

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

Das >/dev/null 2>&1kann &>/dev/nullin Bash gekürzt werden .

Fleischwolf
quelle
7

Skript zum Überprüfen, ob ein Linux-Benutzer vorhanden ist oder nicht

Skript Zum Überprüfen, ob der Benutzer vorhanden ist oder nicht

#! /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
quelle
2
Warum verwenden cat? grep $USER_NAME /etc/passwd >/dev/null 2>&1
Alexx Roche
Ja, Alexx Roche, es besteht keine Notwendigkeit, eine Katze zu verwenden. Ich habe sie verwendet, um das Konzept für Anfänger besser visualisieren zu können.
Bakul Gupta
6

Späte Antwort, fingerzeigt aber auch weitere Informationen zum Benutzer

  sudo apt-get finger 
  finger "$username"
Jackotonye
quelle
OP verwendet möglicherweise kein Debian.
Narendra-Choudhary
3

Eigentlich kann ich das Problem nicht reproduzieren. Das in der Frage geschriebene Skript funktioniert einwandfrei, außer in dem Fall, in dem $ 1 leer ist.

Es gibt jedoch ein Problem im Skript im Zusammenhang mit der Umleitung von stderr. Obwohl die beiden Formen &>und >&existieren, möchten Sie in Ihrem Fall verwenden >&. Sie haben bereits umgeleitet stdout, deshalb &>funktioniert das Formular nicht. Sie können dies auf folgende Weise leicht überprüfen:

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

Sie sehen eine Datei mit dem Namen 1im aktuellen Verzeichnis. Sie möchten 2>&1stattdessen Folgendes verwenden oder Folgendes verwenden:

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

Dies leitet auch um stdoutund stderrzu /dev/null.

Warnung Eine Umleitung stderrzu ist /dev/nullmöglicherweise keine so gute Idee. Wenn etwas schief geht, haben Sie keine Ahnung warum.

Christian Hujer
quelle
3

Benutzerinformationen werden in / etc / passwd gespeichert, sodass Sie mit "grep 'usename' / etc / passwd" überprüfen können, ob der Benutzername vorhanden ist. In der Zwischenzeit können Sie den Shell-Befehl "id" verwenden. Er druckt die Benutzer-ID und die Gruppen-ID. Wenn der Benutzer nicht vorhanden ist, wird die Meldung "Kein solcher Benutzer" ausgegeben.

Yu Chai
quelle
2

Melden Sie sich beim Server an. grep "Benutzername" / etc / passwd Dies zeigt die Benutzerdetails an, falls vorhanden.

Syam
quelle
3
Dies stimmt auch mit jedem Benutzernamen überein, der "Benutzername" enthält. ZB "some_username". Sie würden tun wollenif grep -q "^username:" /etc/passwd; then ...
maedox
2

Mit 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
quelle
1

Abhängig von Ihrer Shell-Implementierung (z. B. Busybox vs. Erwachsener) kann der [Bediener einen Prozess starten und sich ändern$? .

Versuchen

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
quelle
Ändern $?gibt mir die gleiche Ausgabe. Dies ist die Bash-Version:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
Slayedbylucifer
Versuchen Sieif test "$RES" == "0"; then ...
Eugen Rieck
1
$?würde vor dem Ausführen erweitert werden [, das ist also kein Problem.
Chepper
1
Anstatt auf das Ergebnis des Befehls zu testen, können Sie den Befehl direkt testen: 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

Unten finden Sie das Skript zum Überprüfen der Betriebssystemverteilung und zum Erstellen eines Benutzers, falls nicht vorhanden, und zum Nichtstun, wenn ein Benutzer vorhanden ist.

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

Erstellen Sie einen Systembenutzer, some_userfalls dieser nicht vorhanden ist

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

Ich mag diese schöne einzeilige Lösung

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

und im Skript:

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

verwenden:

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