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

时间:2013-05-19 10:21:46

标签: linux bash sed awk

我把它放在一起,但它很糟糕:(例如那里的魔术数字,文字解析..嘘!)

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

这样做的正确方法是什么?

6 个答案:

答案 0 :(得分:12)

某些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

答案 1 :(得分:2)

我不确定你为什么只做&gt; 1000,在redhat系统上从500开始。

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

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

仅用于密码:

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

答案 2 :(得分:2)

/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

答案 3 :(得分:2)

这是另一种方法,只生成一个外部程序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[@]}
}

答案 4 :(得分:1)

所以你只是想从/ 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

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

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

答案 5 :(得分:1)

这是@ 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 -

两个输入中的不同分割模式有点疣;也许你可以以某种方式更优雅地解决这个问题。