如何从uid获取用户名

如何从uid获取用户名

我正在尝试编写一个 bash 脚本,根据用户提供的 uid 显示用户名:

#!/bin/bash

read -p "donner l UID" cheruid

 if [ $(grep -w $cheruid) -n ]
 then
    grep -w $cheruid /etc/passwd | cut -d ":" -f "1" | xargs echo "user is : "
else
    echo "user not found"

fi

当我执行此命令时,终端仅显示提示消息,然后停止工作。

我错过了什么吗?

答案1

使用 GNU id,您可以执行以下操作:

id -un -- "$cheruid"

这将查询帐户数据库(无论是存储在/etc/passwdLDAP、NIS+、RDBMS...中)以查找具有该 uid 的第一个用户名。

一般来说,每个uid只有一个用户名,但这并不能保证,用户帐户数据库中的关键是用户名,而不是用户id。

如果你想知道给定 uid 的所有用户名,你可以这样做:

getent passwd | ID=$cheruid awk -F: '$3 == ENVIRON["ID"] {print $1}'

但这可能不适用于某些不支持的帐户数据库可枚举的(有时大型基于 LDAP 的情况就是如此)。

答案2

$ printf 'User is %s\n' "$( getent passwd 1001 | cut -d : -f 1 )"
User is myself

myself(我的系统上有一个UID 1001的用户)

这将passwd在数​​据库中查询给定的 UID,从该响应中删除用户名,并将结果用作 的参数printf。这在 macOS 上不起作用。

要捕获未知的 UID:

$ printf 'User is %s\n' "$( { getent passwd 1001 || echo 'UNKNOWN USER'; } | cut -d : -f 1 )"
User is myself
$ printf 'User is %s\n' "$( { getent passwd 1002 || echo 'UNKNOWN USER'; } | cut -d : -f 1 )"
User is UNKNOWN USER

作为在命令行上采用任意数量的 UID 的脚本(稍微改变输出):

#!/bin/sh

for uid do
    printf 'User with UID %d is %s\n' "$uid" \
        "$( { getent passwd "$uid" || echo 'NOT KNOWN'; } | cut -d : -f 1 )"
done

测试(这将通过我的 OpenBSD 系统上的一些服务帐户的 UID):

$ sh ./script.sh {110..115}
User with UID 110 is _sndiop
User with UID 111 is NOT KNOWN
User with UID 112 is _syspatch
User with UID 113 is NOT KNOWN
User with UID 114 is NOT KNOWN
User with UID 115 is _slaacd

答案3

帮助了解原始 shell 脚本

if 语句中的测试导致了问题。我建议使用以下 shellscript,

#!/bin/bash

read -p "donner l UID " cheruid

 if [ "$(grep -w "^$cheruid" /etc/passwd)" != "" ]
 then
    grep -w "$cheruid" /etc/passwd | cut -d ":" -f "1" | xargs echo "user is : "
else
    echo "user not found"
fi

编辑1:我添加了一个^在测试中仅查找行开头的匹配项。

编辑2:自从:是一个分隔符,您可以删除它和后面的所有内容,并直接在行中使用结果(echo如果在测试中接受),并将 shellscript 简化为

#!/bin/bash

read -p "donner l UID " cheruid

cheruid=${cheruid%%:*}
user=$(grep -wo "^$cheruid" /etc/passwd)

if [ "$user" != "" ]
then
    echo "user is : $user"
else
    echo "user not found"
fi

这可以帮助您编写一个好的 bash shell 脚本。

查找用户 ID 的有效且更通用的方法id

如果您想要一种有效的方法来检查特定用户名是否存在,<test-name>您可以使用id,如 Stéphane Chazelas 对您的问题的另一个答案所示:

id -un -- <test-name>

例如

id -un -- mehdi

id不仅会发现存储在其中的用户 ID,还会发现/etc/passwd以其他方式管理和存储的用户 ID,例如 LDAP,正如 Matteo Italia 所评论的,LDAP 在专业服务器系统中很常见。


如果你想扫描所有用户

  • 系统用户,在许多用户数 < 1000 的 Linux 系统中

  • “人类”用户,在许多用户数量 >= 1000 的 Linux 系统中

  • 并假设所有用户的数量<2000(如果需要,请修改)

您可以使用以下bash单行代码,它使用一个循环id

for ((i=0;i<2000;i++));do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$i: $name" ;fi;done

如果您只想查看“人类”用户并假设没有跳过任何用户 ID 号(没有删除的用户),则以下bashoneliner 非常快,

i=1000;while true;do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$name" ;else break;fi;i=$((i+1));done

但更可靠的假设是某些ID号可能会被跳过(删除用户),

for ((i=1000;i<2000;i++));do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$i: $name" ;fi;done

还有users打印who用户的用户名的当前登录到当前主机。

答案4

使用 grep 意味着任何数字都将被匹配。作为用户 ID 或组 ID:

$ grep '109' /etc/passwd
uuidd:x:105:109::/run/uuidd:/bin/false
usbmux:x:109:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false

而且也可能会匹配1109。即使称为as grep -w,这也会避免匹配1109。这是一个重要的问题。


使用getent:

$ getent passwd 109
usbmux:x:109:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false

哪个会匹配仅有的找到的第一个用户条目的帐户数据库( /etc/passwdLDAP、 、 ...)的数字 uid,而不是 gid(如果给定数字,如果给定文本则为名称) 。NIS+不适用于 macOS。

所以,脚本可以是:

#!/bin/bash
read -p "donner l UID: " cheruid

if     name=$(getent passwd "$cheruid")
then   name=${name%%:*}
       echo "user is : $name"
else   echo "user not found"
fi

无需 sed、awk、cut 即可获得名称。

相关内容