How to print list of users and groups on FreeBSD?
2 Answers
Developers of the FreeBSD operating system recognized that
/etc/passwdis- a frequently accessed file (each time someone logs in, you perform an
ls[unless resolving numeric IDs is disabled] or similar operation) - that can grow quite large (like thousands of users)
and as such it would be a good idea to optimize read accesses. Therefore since at least FreeBSD version 2.0 (released in 1994), the
passwdfile is stored in Berkeley DB format at/etc/pwd.db.† This file, however, is not human‑readable. For backward compatibility (and to some extent humans) the plaintext database file/etc/passwdis still generated by thepwd_mkdbutility, but it is not necessary anymore for proper functioning of the base system. The/etc/groupfile does not follow this pattern.‡- a frequently accessed file (each time someone logs in, you perform an
If you ensure that
/etc/passwdis kept up‑to‑date (i. e. you exclusively usepw[orvipw] for user management, which implicitly callpwd_mkdb), you can directly utilize text processing utilities such asawkas ooshro already presented. Otherwise you need to unwind the Berkeley DB format first (= convert into text). This can be achieved with FreeBSD’s utilitypw:pw usershow -a # -a stands for allSimilarly there is a sub‑command for
/etc/groupalthough this database is (as of FreeBSD version 14.1) not stored in Berkeley DB format.pw groupshow -a # `user show` and `group show` are recognized, tooCombining the two into a list (the
{ … ; }is a list) and applying some cosmetic filtering:{ pw usershow -a ; pw groupshow -a ; } | cut -d':' -f1 \ | sort -u \ | tr '\n' ' ' \ | fmtThe
cutcommand splits the texts into fields using a colon as the field separator (‑d':') and prints only the first field (‑f1).sortthen performs an alphabetical sorting and prints only unique lines (‑u). Thetransliterate command merges everything into one long line, andfmtwraps this monster line to a reasonable length.However,
pwoperates only on local users/groups. It inspects only the files in/etc(or the directory specified via the‑Vparameter, available since FreeBSD version 3.4). In an environment with centrally‑managed users/groups distributed via the network, you may have other data sources defined in/etc/nsswitch.conf(name service switch). Replacepwwithgetentto obtain a comprehensive list:{ getent passwd ; getent group ; } | cut -d':' -f1 \ | sort -u \ | tr '\n' ' ' \ | fmtThe
getentutility does respect/etc/nsswitch.confso users and groups from other sources such as an LDAP directory are listed, too.You may be wondering about the purpose of the
‑unique flag tosort. It is a somewhat common pattern to have one group for (almost) every user account (esp. for every user account used by humans as the primary login account); so you have a usereoniland also a group by the nameeonil. If output is printed to your terminal (as opposed to a regular text file), you maybe want to highlight users that have a group by the same name:{ getent passwd getent group } | cut -d':' -f1 | sort | uniq -c | while read -r count identifier do # We unnnecessarily emit Set Graphics Rendition Zero so the # character count as determined by `fmt` is balanced across lines. [ ${count:?} -gt 1 ] && tput bold || tput sgr0 printf '%s' "${identifier:?}" tput sgr0 printf ' ' done | fmt -w $((2 * $(tput cols)))The
-coption instructsunique to precede every line with a count of occurrences before duplicate lines were removed. If an identifier was present both in the output ofgetent passwdandgetent group, the count is greater than one.
†: pwd.db is the world‑readable redacted version, /etc/spwd.db contains password hashes, too.
‡: Although NIS (Network Information Service) does create Berkeley DB files for all its databases.
- 184