bash 获取 Linux 上已定义用户列表的 Shell 脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16633614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shell script to get list of defined users on Linux?
提问by Robottinosino
I put this together, but it sucks: (e.g. magic numbers in there, text parsing.. boo!)
我把它放在一起,但它很糟糕:(例如那里的魔术数字,文本解析......嘘!)
awk -F: '{if( >= 1000 && < 2**16-2) print }' /etc/passwd
What's the proper way to do this?
这样做的正确方法是什么?
回答by Stephen Ostermiller
Some unix systems don't use /etc/passwd, or have users that are not specified there. You should use getent passwdinstead of reading /etc/passwd.
一些 unix 系统不使用/etc/passwd,或者有没有在那里指定的用户。你应该使用getent passwd而不是阅读/etc/passwd。
My system also has users that are disabled and can lo longer login with their login command set to /bin/falseor /usr/sbin/nologin. You probably want to exclude them as well.
我的系统也有被禁用的用户,他们可以使用设置为/bin/false或的登录命令不再登录/usr/sbin/nologin。您可能也想排除它们。
Here is what works for me including arheops awk command and ansgar's code to get the min and max from login.defs:
这是对我有用的方法,包括arheops awk 命令和ansgar 的代码,用于从中获取最小值和最大值login.defs:
getent passwd | \
grep -vE '(nologin|false)$' | \
awk -F: -v min=`awk '/^UID_MIN/ {print }' /etc/login.defs` \
-v max=`awk '/^UID_MAX/ {print }' /etc/login.defs` \
'{if(( >= min)&&( <= max)) print }' | \
sort -u
回答by arheops
I am unsure why you do only > 1000, beacuase on redhat system it start from 500.
我不确定你为什么只做 > 1000,因为在 redhat 系统上它从 500 开始。
For me this awk script work ok:
对我来说,这个 awk 脚本工作正常:
awk -F: '{if(( >= 500)&&( <65534)) print }' /etc/passwd
Only uses with passwords:
仅与密码一起使用:
awk -F: '{if(!(( == "!!")||( == "*"))) print }' /etc/shadow
回答by Ansgar Wiechers
Extract the minimum and maximum user IDs from /etc/login.defsand then select the users with IDs between these margins from /etc/passwd:
从中提取最小和最大用户 ID /etc/login.defs,然后选择 ID 介于这些边距之间的用户/etc/passwd:
UID_MIN=$(awk '/^UID_MIN/ {print }' /etc/login.defs)
UID_MAX=$(awk '/^UID_MAX/ {print }' /etc/login.defs)
awk -F: -v min=$UID_MIN -v max=$UID_MAX ' >= min && <= max{print }' /etc/passwd
回答by Alex North-Keys
Here's another approach that only spawns one external program, getent(suggested by @AnsgarWiechers) so that both local and networked passwd databases will be used. This one reduces the number of forks to just one for getentitself. Its portability is limited somewhat by requiring bash4, however.
这是另一种仅生成一个外部程序的方法getent(由@AnsgarWiechers 建议),以便同时使用本地和网络密码数据库。这将叉子的数量减少到只有一个getent。然而,由于需要 bash4,它的可移植性受到了一定的限制。
get_users ()
{
local IFS=$' \t#'
while read var val ; do
case "$var" in
UID_MIN) min="$val" ;;
UID_MAX) max="$val" ;;
esac
done < /etc/login.defs
declare -A users
local IFS=:
while read user pass uid gid gecos home shell; do
if (( min <= uid && uid <= max )) && [[ ! $shell =~ '/(nologin|false)$' ]]; then
users[$user]=1
fi
done < <(getent passwd 2>/dev/null)
echo ${!users[@]}
}
回答by tripleee
Here's a simplification of @StephenOstermiller's answer which gets it done with only two processes. I think it is easier to read, too (provided you are familiar with the awk NR==FNRidiom).
这是@StephenOstermiller 答案的简化版,只需两个过程即可完成。我认为它也更容易阅读(前提是您熟悉 awkNR==FNR习语)。
getent passwd |
awk 'NR==FNR { if ( ~ /^UID_(MIN|MAX)$/) m[] = ; next }
{ split (cut -d":" -f1 /etc/passwd
, a, /:/);
if (a[3] >= m["UID_MIN"] && a[3] <= m["UID_MAX"] && a[7] !~ /(false|nologin)$/)
print a[1] }' /etc/login.defs -
The different split patterns in the two inputs is a bit of a wart; maybe you could fix that more elegantly somehow.
两个输入中的不同拆分模式有点棘手;也许你可以以某种方式更优雅地解决这个问题。
回答by mart1n
So you're just trying to get a list of all users from /etc/passwd? If so, I believe this would be an easier solution:
所以您只是想从 /etc/passwd 中获取所有用户的列表?如果是这样,我相信这将是一个更简单的解决方案:
grep -E ":[0-9]{4,6}:[0-9]{4,6}:" /etc/passwd | cut -d: -f1
Edit:
编辑:
In case you only want a list of user-defined users (not the system users), you can use one of these:
如果您只需要用户定义的用户列表(而不是系统用户),您可以使用以下其中之一:
grep /home /etc/passwd | cut -d: -f1
^ This assumes your system uses 1000 and up for UID and GID for user-defined users
^ 这假设您的系统使用 1000 及以上作为用户定义用户的 UID 和 GID
##代码##^ This assumes every user-defined user has a home directory.
^ 这假设每个用户定义的用户都有一个主目录。
Other solutions depend on more detailed criteria and your system settings.
其他解决方案取决于更详细的标准和您的系统设置。

