繁体   English   中英

Shell脚本获取Linux上已定义用户的列表?

[英]Shell script to get list of defined users on Linux?

我把它们放在一起,但是很烂:(例如,其中的魔术数字,文本解析..嘘!)

awk -F: '{if($3 >= 1000 && $3 < 2**16-2) print $1}' /etc/passwd

正确的方法是什么?

某些Unix系统不使用/etc/passwd ,或者有未在其中指定用户的用户。 您应该使用getent passwd而不是读取/etc/passwd

我的系统还具有被禁用的用户,可以使用将他们的登录命令设置为/bin/false/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

我不确定为什么只做> 1000,因为在redhat系统上它从500开始。

对我来说,这个awk脚本可以正常工作:

awk -F: '{if(($3 >= 500)&&($3 <65534)) print $1}' /etc/passwd

仅与密码一起使用:

awk -F: '{if(!(( $2 == "!!")||($2 == "*"))) print $1}' /etc/shadow 

/etc/login.defs提取最小和最大用户ID,然后从/etc/passwd选择具有这些边距之间的ID的用户:

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

这是另一种方法,它仅生成一个外部程序getent (由@AnsgarWiechers建议),以便将使用本地和联网的passwd数据库。 这其中减少了叉只是一个数量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[@]}
}

因此,您只是想从/ etc / passwd获取所有用户的列表? 如果是这样,我相信这将是一个更简单的解决方案:

cut -d":" -f1 /etc/passwd

编辑:

如果只需要用户定义的用户列表(而不是系统用户),则可以使用以下用户之一:

grep -E ":[0-9]{4,6}:[0-9]{4,6}:" /etc/passwd | cut -d: -f1

^假设您的系统为用户定义的用户使用UID和GID为1000以上

grep /home /etc/passwd | cut -d: -f1

^这假设每个用户定义的用户都有一个主目录。

其他解决方案取决于更详细的条件和您的系统设置。

这是@StephenOstermiller答案的简化形式,只需两个过程即可完成。 我认为它也更容易阅读(只要您熟悉awk NR==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 -

两个输入中不同的分割模式有点像疣。 也许您可以通过某种方式更优雅地解决该问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM