许多系统有一个getent
对list命令或查询的内容名称服务数据库一样passwd
,group
,services
,protocols
...
getent passwd | cut -d: -f6
将列出可以枚举的数据库中所有用户的主目录(第6 个冒号分隔的字段)。
用户名本身在第一个字段中,因此对于用户名列表:
getent passwd | cut -d: -f1
(请注意,这并不意味着那些用户可以登录系统或已经创建了其主目录,但是它们对于系统是已知的,可以转换为用户标识)。
对于无法枚举的数据库,您可以尝试分别查询每个可能的用户ID:
getent passwd {0..65535} | cut -d: -f1,6
(这里假设uid在65535处停止(某些系统支持更多)和一个支持zsh {x..y}
形式的大括号扩展的shell )。但是您不希望在用户数据库联网(并且本地缓存有限)的系统上经常这样做,例如LDAP,NIS +,SQL ...,因为这可能意味着大量的网络流量(并在目录服务器上加载) )进行所有这些查询。
这也意味着,如果有多个用户共享同一个uid,则每个uid只会获得一个条目,因此会错过其他条目。
如果没有getent
,您可以诉诸perl
:
perl -le 'while (@e = getpwent) {print $e[7]}'
用于getent passwd
($e[0]
用于用户名),或:
perl -le 'for ($i=0;$i<65536;++$i) {
if (@e = getpwuid $i) {print $e[0] ": " $e[7]}}'
对于getent passwd {0..65535}
相同的警告。
在shell中,您可以~user
用来获取的主目录user
,但在大多数shell中,该目录仅适用于有限的用户名集(该~
扩展操作符支持的用户名中允许的字符列表随shell的不同而不同)以及几个外壳程序(包括bash
)~$user
将不起作用(eval
当用户名存储在变量中时,您需要诉诸于此)。而且,您仍然必须找到一种获取用户名列表的方法。
一些外壳程序具有内置支持来获取用户名列表。
bash
:compgen -u
将返回可以枚举的数据库中的用户列表。
zsh
:$userdirs
关联数组将用户名映射到其主目录(也限于可以枚举的数据库,但是如果您对~user
不可枚举数据库中的用户进行扩展,则会将一个条目添加到$userdirs
)。因此,您可以执行以下操作:
printf '%s => %s\n' "${(kv@)userdirs}"
列出用户及其主目录。
但这仅在zsh
交互式时有效。
tcsh
,fish
还有yash
另外三个可以完成用户名的shell(例如,在完成~<Tab>
参数时),但是看起来它们不能让您以编程方式获取该用户名列表。