我经常想要获取与用户 ID 相关联的登录名,并且因为它已被证明是一个常见的用例,所以我决定编写一个 shell 函数来执行此操作。虽然我主要使用 GNU/Linux 发行版,但我尝试将我的脚本编写为尽可能可移植,并检查我所做的是否与 POSIX 兼容。
解析/etc/passwd
我尝试的第一种方法是解析/etc/passwd
(使用awk
)。
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
但是,这种方法的问题是登录可能不是本地的,例如,用户身份验证可能通过 NIS 或 LDAP。
使用getent
命令
使用getent passwd
比解析更便携,/etc/passwd
因为这也查询非本地 NIS 或 LDAP 数据库。
getent passwd "$uid" | cut -d: -f1
不幸的是,getent
POSIX 似乎没有指定该实用程序。
使用id
命令
id
是用于获取有关用户身份的数据的 POSIX 标准化实用程序。
BSD 和 GNU 实现接受用户 ID 作为操作数:
这意味着它可用于打印与用户 ID 关联的登录名:
id -nu "$uid"
但是,在 POSIX 中没有指定提供用户 ID 作为操作数;它只描述了使用登录名作为操作数。
结合以上所有
我考虑将上述三种方法组合成如下内容:
get_username(){
uid="$1"
# First try using getent
getent passwd "$uid" | cut -d: -f1 ||
# Next try using the UID as an operand to id.
id -nu "$uid" ||
# As a last resort, parse `/etc/passwd`.
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
}
然而,这很笨重、不优雅,而且——更重要的是——不够健壮;如果用户 ID 无效或不存在,它将以非零状态退出。在我编写一个更长更笨重的 shell 脚本来分析和存储每个命令调用的退出状态之前,我想我会在这里问:
是否有一种更优雅、更便携(POSIX 兼容)的方式来获取与用户 ID 关联的登录名?