检查用户是否存在


164

我想创建一个脚本来检查用户是否存在。我正在使用以下逻辑:

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

因此,如果用户存在,那么我们就成功了,否则该用户不存在。我在bash脚本中放置了以下命令,如下所示:

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

现在,我的脚本总是说该用户存在,无论如何:

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

为什么上述条件总是评估为TRUE并说用户存在?

我要去哪里错了?

更新:

阅读所有答复后,我在脚本中发现了问题。问题是我重定向getent输出的方式。因此,我删除了所有重定向内容,并使该getent行如下所示:

getent passwd $user  > /dev/null

现在我的脚本运行正常。


我认为,当您使用时,您$?会获得test命令的返回码。请参阅下面的答案。
user000001 2013年

那是您运行的确切代码吗?调用之间不存在“回声”调试语句getent和你的if说法?这将导致$?检查的退出状态echo,而不是您对的调用getent
chepner 2013年

4
是的,我想你的意思是2>&1不是2&>1
蒂姆·卢德温斯基

代码适用于非空输入,但是如果$1未设置,则if语句将返回true。根据我的测试,解决方案是$1用双引号引起来:getent passwd "$1" > /dev/null 2&>1
文斯

请注明答案
Efren '18

Answers:


292

您还可以通过id命令检查用户。

id -u name为您提供该用户的ID。如果用户不存在,您将获得命令返回值($?1



24
很好的答案-进行一些细微调整就可以很好地工作... user_exists = $(id -u user> / dev / null 2>&1; echo $?)user_exists = 0如果存在“ user”,则为1,否则为1
Pancho

5
@Pancho我认为您的变量应命名为user_doesnt_exist
Will Sheppard

1
@WillSheppard:在一般级别上,我认为bash中的布尔处理尚不明确,我通常在代码中避免隐式布尔推断。以下内容引起有趣的阅读,并且有趣的是,出于bash的目的,都赞成0 = true和<not 0> = false,虽然不是事实,但也要与我从布尔角度使用的变量名称对齐:stackoverflow.com/a/5431932 / 3051627stackoverflow.com/questions/2933843/…
Pancho

2
感谢@Pancho的评论,我可以做到这一点,只需将错误发送到void并执行即可validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }。那,如果用户存在,几乎返回1,否则返回0。
lu1s

31

你为什么不简单地使用

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

如果该用户存在,它将返回1(因为用户最多有1个条目),否则返回0。


19
如果服务器使用其他系统来管理NIS或LDAP等用途,则此方法将无效。在这种情况下,您可以使用getent passwd | grep -c '^username:'
Toby Jackson

1
如果您有用户名,则返回1,比如说“ test1”,并想创建一个新的用户名“ test”。
Marin Nedea '18

2
@MarinNedea :用户名后的冒号通过与字段分隔符匹配来防止子字符串匹配,因此不会发生您描述的效果。
斯特凡·古里康

30

无需显式检查退出代码。尝试

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

如果这不起作用,则说明您的出问题了getent,或者您定义的用户数量超出了您的想象。


23

这就是我在Freeswitchbash启动脚本中所做的事情:

# 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

我建议使用id命令,因为它可以测试有效的用户存在wrt passwd文件条目,而这不必要意味着相同:

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

注意:0是根uid。


12

我以这种方式使用它:

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

9

到目前为止,最简单的解决方案是:

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

>/dev/null 2>&1可缩短到&>/dev/nullBash中。


是的,谢谢!
Zane Hitchcox

7

检查Linux用户是否存在的脚本

脚本检查用户是否存在

#! /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
为什么要使用catgrep $USER_NAME /etc/passwd >/dev/null 2>&1
Alexx Roche

是的,Alexx Roche,不需要使用cat,我使用它是为了有更好的方法为初学者形象化的概念。
Bakul Gupta


3

实际上,我无法重现该问题。问题中编写的脚本可以正常工作,但$ 1为空的情况除外。

但是,脚本中存在与重定向有关的问题stderr。虽然这两种形式&>>&存在,你的情况,你要使用>&。您已经重定向了stdout,这就是为什么表单&>不起作用的原因。您可以通过以下方式轻松进行验证:

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

您将1在当前目录中看到一个名为的文件。您想使用它2>&1来代替,或使用以下方法:

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

这也会重定向到stdout和。stderr/dev/null

警告重定向stderr/dev/null可能不是一个好主意。如果出现问题,您将不知道为什么。


3

用户信息存储在/ etc / passwd中,因此您可以使用“ grep'usename'/ etc / passwd”来检查用户名是否存在。同时您可以使用“ id” shell命令,它将显示用户ID和组ID,如果该用户不存在,则将显示“无此用户”消息。


2

登录到服务器。 grep“用户名” / etc / passwd 如果存在,它将显示用户详细信息。


3
这也将匹配任何包含“用户名”的用户名。例如“ some_username”。您可能想要做if grep -q "^username:" /etc/passwd; then ...
maedox

2

使用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

根据您的Shell实施(例如Busybox与成人),[操作员可能会开始更改流程$?

尝试

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

变化$?给了我相同的输出。这是bash版本:GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
slayedbylucifer

试试if test "$RES" == "0"; then ...
Eugen Rieck

1
$?会在[运行前进行扩展,所以这不是问题。
chepner 2013年

1
您可以直接测试命令,而不必测试命令的结果: 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

以下是检查OS分发并创建User(如果不存在)和不执行任何操作(如果用户存在)的脚本。

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

创建系统用户(some_user如果不存在)

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

0

我喜欢这个不错的单线解决方案

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

并在脚本中:

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

用:

[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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.