我把它放在一起,但它很烂:(例如那里的幻数,文本解析......嘘!)
awk -F: '{if($3 >= 1000 && $3 < 2**16-2) print $1}' /etc/passwd
这样做的正确方法是什么?
一些 unix 系统不使用/etc/passwd
,或者有没有在那里指定的用户。你应该使用getent passwd
而不是阅读/etc/passwd
。
/bin/false
我的系统也有一些用户被禁用,他们的登录命令设置为or时就无法再登录/usr/sbin/nologin
。您可能还想排除它们。
以下是对我有用的方法,包括 arheops awk 命令和 ansgar 的代码,用于从中获取最小值和最大值login.defs
:
getent passwd | \
grep -vE '(nologin|false)$' | \
awk -F: -v min=`awk '/^UID_MIN/ {print $2}' /etc/login.defs` \
-v max=`awk '/^UID_MAX/ {print $2}' /etc/login.defs` \
'{if(($3 >= min)&&($3 <= max)) print $1}' | \
sort -u
从 中提取最小和最大用户 ID /etc/login.defs
,然后从 中选择 ID 介于这些边距之间的用户/etc/passwd
:
UID_MIN=$(awk '/^UID_MIN/ {print $2}' /etc/login.defs)
UID_MAX=$(awk '/^UID_MAX/ {print $2}' /etc/login.defs)
awk -F: -v min=$UID_MIN -v max=$UID_MAX '$3 >= min && $3 <= max{print $1}' /etc/passwd
我不确定你为什么只做> 1000,因为在redhat系统上它从500开始。
对我来说,这个 awk 脚本工作正常:
awk -F: '{if(($3 >= 500)&&($3 <65534)) print $1}' /etc/passwd
仅与密码一起使用:
awk -F: '{if(!(( $2 == "!!")||($2 == "*"))) print $1}' /etc/shadow
这是另一种只生成一个外部程序的方法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[@]}
}
这是@StephenOstermiller 的答案的简化,只需两个过程即可完成。我认为它也更容易阅读(前提是您熟悉 awkNR==FNR
习语)。
getent passwd |
awk 'NR==FNR { if ($1 ~ /^UID_(MIN|MAX)$/) m[$1] = $2; next }
{ split ($0, a, /:/);
if (a[3] >= m["UID_MIN"] && a[3] <= m["UID_MAX"] && a[7] !~ /(false|nologin)$/)
print a[1] }' /etc/login.defs -
两个输入中的不同拆分模式有点棘手。也许你可以以某种方式更优雅地解决这个问题。
所以你只是想从/etc/passwd 中获取所有用户的列表?如果是这样,我相信这将是一个更简单的解决方案:
cut -d":" -f1 /etc/passwd
编辑:
如果您只需要用户定义的用户列表(而不是系统用户),您可以使用以下之一:
grep -E ":[0-9]{4,6}:[0-9]{4,6}:" /etc/passwd | cut -d: -f1
^ 这假设您的系统为用户定义的用户使用 1000 及以上的 UID 和 GID
grep /home /etc/passwd | cut -d: -f1
^ 这假设每个用户定义的用户都有一个主目录。
其他解决方案取决于更详细的标准和您的系统设置。