检查用户是否存在

246

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

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

如果用户存在,则操作成功,否则用户不存在。我已将上述命令放在以下Bash脚本中:

所以,如果用户存在,那么我们就成功了,否则用户不存在。我已将上述命令放入下面的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
你运行的是完全相同的代码吗?在调用getentif语句之间没有“echo”调试语句吗?否则会导致$?检查echo的退出状态,而不是你对getent的调用。 - chepner
5
是的,我认为你的意思是使用2>&1而不是2&>1 - Tim Ludwinski
代码适用于非空输入,但如果 $1 未设置,则 if 语句将返回 true。根据我的测试,解决方案是将 $1 包装在双引号中:getent passwd "$1" > /dev/null 2&>1 - Vince
请标记一个答案。 - Efren
@slayedbylucifer,你的getent命令无法运行的原因是你打错了:2&>1 __不是有效的重定向__。 - jimis
19个回答

388

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

id -u name会给出该用户的ID。 如果用户不存在,您将得到命令返回值($?1

正如其他答案指出的那样:如果您只想检查用户是否存在,直接使用ifid,因为if已经检查了退出码。没必要纠结于字符串、[$?$()

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

如果你将这段代码转化为一个函数或脚本,我建议你也适当地设置你的退出代码。
#!/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`

3
那是我使用的。请参见http://superuser.com/questions/336275/find-out-if-user-name-exists - guettli
24
很好的回答 - 只需进行微小的调整即可完美地运作...... user_exists=$(id -u user > /dev/null 2>&1; echo $?) 如果"user"存在,则user_exists等于0,否则为1。 - Pancho
5
@Pancho,我认为你的变量应该被命名为“user_doesnt_exist”。 - Will Sheppard
1
@WillSheppard:在一般情况下,我认为Bash中的布尔处理不够清晰,因此我通常避免在我的代码中使用隐式布尔推断。以下内容很有趣,有趣的是两者都支持0=true和<not 0>=false用于Bash目的,并且虽然不是法定的,但从布尔角度来看与我使用的变量名称相符:https://dev59.com/km035IYBdhLWcg3wbPU5#5431932。https://dev59.com/MXA85IYBdhLWcg3wHvw0。 - Pancho
2
感谢@Pancho的评论,我成功地通过将错误发送到虚空并执行validuser(){ [[ -n $(id -u "$1" 2>/dev/null) ]] && echo 1 || echo 0; }来实现。这基本上会返回1(如果用户存在)或0(如果不存在)。 - lu1s
显示剩余9条评论

40

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

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

如果那样不起作用,那么您的getent存在问题,或者您定义的用户比您想象的更多。


38

为什么不直接使用?

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

如果用户存在,则返回1(因为用户最多只有1个条目),如果不存在则返回0。


23
如果服务器使用其他系统来管理用户,例如NIS或LDAP,则此方法不起作用。在这种情况下,您可以使用“getent passwd | grep -c'^用户名:'”。 - Toby Jackson
1
如果您已经有一个用户名,比如“test1”,并想创建一个名为“test”的新用户名,则此代码将返回1。 - Marin N.
2
@MarinNedea 在用户名后面加上冒号 : 是为了防止子字符串匹配,它会与字段分隔符进行匹配,因此您所描述的情况不会发生。 - Stéphane Gourichon
1
/etc/passwd 取决于 nsswitch.conf 的设置。 - Gert van den Berg

27

迄今为止最简单的解决方案:

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

在Bash中,>/dev/null 2>&1 可以简写为 &>/dev/null,如果你只想知道用户不存在

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

2
最佳答案 - MestreLion
这应该是被接受的答案。 - undefined

27

这是我在一个 Freeswitch 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
我是这样使用它的:
if [ $(getent passwd $user) ] ; then
        echo user $user exists
else
        echo user $user doesn\'t exists
fi

1
一种不好的方法。你可以摆脱 [ ]$(),直接检查 getent退出码 而不是使用它的 _输出_。 - MestreLion

14

我建议使用id命令,因为它可以测试与passwd文件条目相比是否存在有效用户,这并不意味着两者必须相同:

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

注意:0是根用户ID。


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

6
为什么要使用 catgrep $USER_NAME /etc/passwd >/dev/null 2>&1 - Alexx Roche
Alexx Roche,不需要使用cat命令,我使用了它以便初学者更好地理解概念。 - Bakul Gupta
不必要地使用cat命令,依赖于nsswitch仅配置为使用文件。 - Gert van den Berg
如果输入的用户名与passwd中每行的其他部分匹配,则此方法将无法正常工作。 - Anutrix

6
晚了一些,但是 finger 命令可以显示有关用户的更多信息。
  sudo apt-get finger 
  finger "$username"

1
OP 可能没有使用 Debian。 - narendra-choudhary

5

使用sed:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接