slayedbylucifer
slayedbylucifer

Reputation: 23532

Check Whether a User Exists

I want to create a script to check whether a user exists. I am using the logic below:

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

So if the user exists, then we have success, else the user does not exist. I have put above command in the bash script as below:

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

Now, my script always says that the user exists no matter what:

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

Why does the above condition always evaluate to be TRUE and say that the user exists?

Where am I going wrong?

UPDATE:

After reading all the responses, I found the problem in my script. The problem was the way I was redirecting getent output. So I removed all the redirection stuff and made the getent line look like this:

getent passwd $user > /dev/null

Now my script is working fine.

Upvotes: 256

Views: 354837

Answers (19)

Kent
Kent

Reputation: 195289

You can also check user by id command.

id -u name gives you the id of that user. If the user doesn't exist, you got command return value ($?) 1.

And as other answers pointed out: if all you want is just to check if the user exists, use if with id directly, as if already checks for the exit code. There's no need to fiddle with strings, [, $? or $():

if id "$1" >/dev/null 2>&1; then
    echo 'user found'
else
    echo 'user not found'
fi

(no need to use -u as you're discarding the output anyway)

Also, if you turn this snippet into a function or script, I suggest you also set your exit code appropriately:

#!/bin/bash
user_exists(){ id "$1" &>/dev/null; } # silent, it just sets the exit code
if user_exists "$1"; code=$?; then  # use the function, save the code
    echo 'user found'
else
    echo 'user not found' >&2  # error messages should go to stderr
fi
exit $code  # set the exit code, ultimately the same set by `id`

Upvotes: 400

Fleshgrinder
Fleshgrinder

Reputation: 16303

By far the simplest solution:

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

The >/dev/null 2>&1 can be shortened to &>/dev/null in Bash, and if you only want to know if a user does not exist:

if ! id -u "$user" >/dev/null 2>&1; then
    echo 'user missing'
fi

Upvotes: 27

#!/bin/bash
read -p "Enter your Login Name: " loginname
home=`grep -w $loginname /etc/passwd | cut -ef:6 -d:`
if [ $home ]
    echo "Exists"
else
    echo "Not Exist"
fi

Upvotes: 0

wiktorm
wiktorm

Reputation: 1

echo "$PASSWORD" | su -c "cd /" "$USER"
if [ "$?" = "0" ];then
 echo "OK"
else
 echo "Error"
fi

Upvotes: 0

nir vizel
nir vizel

Reputation: 21

I like this nice one line solution

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

and in 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

use:

[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

Upvotes: 1

luchaninov
luchaninov

Reputation: 6806

Create system user some_user if it doesn't exist

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

Upvotes: 1

Santosh Garole
Santosh Garole

Reputation: 1966

Below is the script to check the OS distribution and create User if not exists and do nothing if user exists.

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

Upvotes: 1

Stephane
Stephane

Reputation: 5076

Using sed:

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

Upvotes: 5

Andy
Andy

Reputation: 77

user infomation is stored in /etc/passwd, so you can use "grep 'usename' /etc/passwd" to check if the username exist. meanwhile you can use "id" shell command, it will print the user id and group id, if the user does not exist, it will print "no such user" message.

Upvotes: 4

Bakul Gupta
Bakul Gupta

Reputation: 103

Script to Check whether Linux user exists or not

Script To check whether the user exists or not

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

Upvotes: 7

Daniel Sokolowski
Daniel Sokolowski

Reputation: 12498

This is what I ended up doing in a Freeswitch bash startup script:

# 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

Upvotes: 27

Takeda
Takeda

Reputation: 149

I was using it in that way:

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

Upvotes: 14

jackotonye
jackotonye

Reputation: 3853

Late answer but finger also shows more information on user

  sudo apt-get finger 
  finger "$username"

Upvotes: 7

syam
syam

Reputation: 825

Login to the server. grep "username" /etc/passwd This will display the user details if present.

Upvotes: 2

Valdas Rapševičius
Valdas Rapševičius

Reputation: 416

I suggest to use id command as it tests valid user existence wrt passwd file entry which is not necessary means the same:

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

Note: 0 is root uid.

Upvotes: 14

Christian Hujer
Christian Hujer

Reputation: 17995

Actually I cannot reproduce the problem. The script as written in the question works fine, except for the case where $1 is empty.

However, there is a problem in the script related to redirection of stderr. Although the two forms &> and >& exist, in your case you want to use >&. You already redirected stdout, that's why the form &> does not work. You can easily verify it this way:

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

You will see a file named 1 in the current directory. You want to use 2>&1 instead, or use this:

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

This also redirects stdout and stderr to /dev/null.

Warning Redirecting stderr to /dev/null might not be such a good idea. When things go wrong, you will have no clue why.

Upvotes: 5

chepner
chepner

Reputation: 532538

There's no need to check the exit code explicitly. Try

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

If that doesn't work, there is something wrong with your getent, or you have more users defined than you think.

Upvotes: 40

Eugen Rieck
Eugen Rieck

Reputation: 65342

Depending on your shell implementation (e.g. Busybox vs. grown-up) the [ operator might start a process, changing $?.

Try

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

Upvotes: 3

poitroae
poitroae

Reputation: 21377

Why don't you simply use

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

It will return 1 (since a user has max. 1 entry) if the user exists and 0 if it doesn't.

Upvotes: 38

Related Questions