From 6d9b5c4f8a9a8f1628379a91f7baff033c5b3b4a Mon Sep 17 00:00:00 2001 From: Ezri Brimhall Date: Wed, 2 Oct 2024 13:33:08 -0600 Subject: [PATCH] Updated user report Now uses an AWK one-liner, improving performance due to making fewer calls to getent. This might be have been anissue with certain remote-user passwd backends that do not cache a list of users. Additionally, added fallback to simply scan /etc/passwd if getent is not available on the system. --- user-report/report.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/user-report/report.sh b/user-report/report.sh index 84606e9..d836ab9 100755 --- a/user-report/report.sh +++ b/user-report/report.sh @@ -1,14 +1,26 @@ #!/bin/bash # Returns a list of all users on the system with UID >= 1000 and their home directory and shell -# Sorted lexicographically by uid +# Sorted lexicographically by username # Uses getent passwd so as to include remote users (e.g. LDAP) in the list # getent passwd returns a list of all users on the system, local and remote # it may return duplicates, since a user might be listed identically in multiple nsswitch databases (e.g. files and systemd) -for uid in $(getent passwd | cut -d: -f3 | sort | uniq); do - if [ $uid -ge 1000 ]; then - # Use AWK to parse the output of the passwd entry - getent passwd $uid | awk -F: '{print "User: " $1 ", UID: " $3 ", Home: " $6 ", Shell: " $7}' - fi -done +# as such, we sort the list and remove duplicates with uniq before processing it + +# I'm also removing the "nobody" user, since it's a special case and not a real user + +# passwd entries have the following format: +# $username:x:$uid:$gid:$displayname:$home:$shell +# e.g. root:x:0:0::/root:/bin/bash +# Awk is 1-indexed, so $1 is the username, $2 is the x, $3 is the uid, etc. +# the fields we care about are: +# $1: username +# $3: uid +# $7: shell +if which getent &>/dev/null; then + getent passwd | sort | uniq | awk -F: '{if ($3 >= 1000 && $1 != "nobody") print "User: " $1 ", UID: " $3 ", Shell: " $7}' +else + echo "getent not found, falling back to /etc/passwd" >&2 + awk -F: '{if ($3 >= 1000 && $1 != "nobody") print "User: " $1 ", UID: " $3 ", Shell: " $7}' /etc/passwd +fi