Reputation: 23532
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
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
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
Reputation: 71
#!/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
Reputation: 1
echo "$PASSWORD" | su -c "cd /" "$USER"
if [ "$?" = "0" ];then
echo "OK"
else
echo "Error"
fi
Upvotes: 0
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
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
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
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
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
Reputation: 103
Script to Check whether Linux 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
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
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
Reputation: 3853
Late answer but finger
also shows more information on user
sudo apt-get finger
finger "$username"
Upvotes: 7
Reputation: 825
Login to the server. grep "username" /etc/passwd This will display the user details if present.
Upvotes: 2
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
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
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
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
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