检查用户是否在组中

时间:2013-08-25 16:45:04

标签: bash

我有一台运行的服务器,我使用php运行bash脚本来验证用户的某些信息。例如,我设置了一个虚拟主机服务器,为了能够将另一个域添加到他们的帐户,我想验证用户是否实际上是“客户”组的成员。最好的方法是什么?

我搜索过谷歌,但它提供的方法是检查用户或群组是否存在,所以谷歌现在不是一个很大的帮助。

13 个答案:

答案 0 :(得分:30)

尝试这样做:

username=ANY_USERNAME
if getent group customers | grep &>/dev/null "\b${username}\b"; then
    echo true
else
    echo false
fi

username=ANY_USERNAME
if groups $username | grep &>/dev/null '\bcustomers\b'; then
    echo true
else
    echo false
fi

答案 1 :(得分:28)

if id -nG "$USER" | grep -qw "$GROUP"; then
    echo $USER belongs to $GROUP
else
    echo $USER does not belong to $GROUP
fi

说明:

  1. id -nG $USER显示用户所属的群组名称。
  2. grep -qw $GROUP默认检查输入中是否存在$ GROUP作为整个单词。

答案 2 :(得分:5)

我知道这可能是旧帖子,但万一这样做也很好:

id -Gn"用户名" | grep -c" groupname"

如果有任何数字>返回0然后用户是该组的成员。

答案 3 :(得分:4)

你可以使用 groups $username_here | grep -q '\busergroup\b'

如果找到匹配,则exitcode为0,如果未找到匹配,则为1。

user_in_group()
{
    groups $1 | grep -q "\b$2\b"
}

您可以将此功能用作user_in_group userfoo groupbar

答案 4 :(得分:3)

使用零字符分隔的固定字符串grep检查组成员资格的稍微更防错的方法。

if id -nGz "$USER" | grep -qzxF "$GROUP"
then
    echo User \`$USER\' belongs to group \`$GROUP\'
else
    echo User \`$USER\' does not belong to group \`$GROUP\'
fi

或使用长选项

if id --name --groups --zero "$USER" | 
   grep --quiet --null-data --line-regexp --fixed-strings "$GROUP"
then
    echo User \`$USER\' belongs to group \`$GROUP\'
else
    echo User \`$USER\' does not belong to group \`$GROUP\'
fi

答案 5 :(得分:1)

听起来像另一个答案:

username='myuser'
if grep -q -E "^customers:.*[:,]$username(,.*|\b)" /etc/group; then
    echo 'true'
else
    echo 'false'
fi

正如sputnick报告的那样,groups命令的输出可能取决于您的操作系统。 我不确定这段代码将如何执行,但最有可能它会做得更好。

答案 6 :(得分:0)

username='myuser'
if groups "$username" | grep -q -E ' customers(\s|$)'; then
    echo 'yes'
else
    echo 'no'
fi

我必须澄清一件事: groups可能会返回这样的内容:

myuser : cdrom floppy sudo audio dip video plugdev fuse

但是当您的用户名为customers时,有一个角落:

customers : cdrom floppy sudo audio dip video plugdev fuse

例如,\bcustomers\b模式将找到用户名,而不是组。所以你必须确保它不是输出中的第一个单词。

另外,另一个好的正则表达式是:

grep -q ' customers\b'

答案 7 :(得分:0)

我的版本不依赖于grep。

第一个参数(必填):组
第二个参数(可选,默认为当前用户)

isInGroup(){
   group="$1"
   user="${2:-$(whoami)}"
   ret=false 
   for x in $(groups "$user" |sed "s/.*://g")
   do [[ "$x" == "$group" ]] && { ret=true ; break ; }
   done
   eval "$ret"
}

答案 8 :(得分:0)

对于所有那些golf粉丝:

ingroup(){ [[ " "`groups $2`" " == *" $1 "* ]]; }

用法:ingroup group [user]

示例:

if ingroup video; then
  echo 'Enjoy the show!'
fi

此解决方案使用groups,因此如果用户名作为其输出的一部分返回,它就会被蜇到,这不是我的系统,没有考虑到品味! (请注意,用户通常是与用户名称相同的群组的一部分,因此无论如何它可能都不重要。)您可以尝试:[[群组$ 2 " " == *" $1 "* ]]赢得&# 39;看看groups输出中的第一个单词。任何比这更复杂的事情,我们都会超过标准。

TL; DR关键是我利用了内置的globbing来查找子字符串。

答案 9 :(得分:0)

使用零定界符按行分割:

id -nGz user | tr '\0' '\n' | grep '^group$'

答案 10 :(得分:0)

前一段时间,我编写了一个shell函数来检查用户是否是组的成员。为了最大程度地提高可移植性,我希望它与POSIX兼容(尽管此问题标记为bash,但此功能仍然有效)。为了提高性能,我想尽可能地使用内置的shell功能:它使用的唯一外部命令是id,这是POSIX标准化的实用程序,用于获取有关用户身份的数据。

is_in_group()
{
  groupname="$1"
  # The second argument is optional -- defaults to current user.
  current_user="$(id -un)"
  user="${2:-$current_user}"
  for group in $(id -Gn "$user") ; do
    if [ "$group" = "$groupname" ]; then
      return 0
    fi
  done
  # If it reaches this point, the user is not in the group.
  return 1
}

用于测试肯定和否定情况的示例用法-并确保其正常处理不存在的用户名:

g=mail
userlist="anthony postfix xxx"
for u in $userlist; do
  if is_in_group "$g" "$u"; then
    printf "%s is in ‘%s’\n" "$u" "$g"
  else
    printf "%s is NOT in ‘%s’\n" "$u" "$g"
  fi
done

运行以上命令将显示以下输出:

anthony is NOT in ‘mail’
postfix is in ‘mail’
id: ‘xxx’: no such user
xxx is NOT in ‘mail’

尚未针对组或用户的名称中包含空格或其他不寻常字符的情况进行过测试,但一些研究表明,此类名称不合法:Group Name的POSIX基本定义指出:

  

要在符合标准的系统中移植,该值包括   便携式文件名字符集中的字符。

Portable Filename Character Set被指定为字母数字字符,A-Z,a-z,0-9,以及点号,下划线和连字符号。

答案 11 :(得分:0)

重击单行:

[[ " $(groups) " =~ ' spark ' ]] && echo 'Is in group'

重击多行:

if [[ " $(groups) " =~ ' spark ' ]]; then
    echo 'Is in group'
fi

答案 12 :(得分:0)

这是我的。

首先是长版

#!/bin/bash
if [[ $# -eq 0 ]]
then
  echo "Usage: $0 [-v] user group"
  echo ""
  echo "  -v verbose. Outputs a sentence for humans."
  echo ""
  echo "Example:"
  echo ""
  echo "  ingroup wilma sudo && echo Wilma has superpowers"
  exit 2
fi

if [[ "$1" == "-v" ]]
then
  verbose=1
  shift
fi

user=$1
grp=$2
# Get groups output
grps=$(groups $user)
# Create a regexp. Note that we must create the regexp in a var
# because it's the only way to allow for spaces in the regexp.
# Strangely we provide this var unquoted when using it; even 
# though it has spaces.
re="^.*:.* $2 "
if [[ "$grps" =~ $re ]]
then
  [[ -n "$verbose" ]] && echo "$user is in group $grp"
  # Success error code
  exit 0
else
  [[ -n "$verbose" ]] && echo "$user is not in group $grp"
  # Fail error code
  exit 1
fi

是否希望将简短版本用作函数?

ingroup() {
  re="^.*:.* $2 "
  [[ "$(groups $1) " =~ $re ]] || return 1
}

测试

# Basic positive test
$ ingroup -v wilma sudo && echo 'and therefore is cool'
wilma is in group sudo
and therefore is cool

# Basic negative test
$ ingroup -v wilma myprivateclub || echo 'sorry bout that'
wilma is not in group sudo
sorry bout that

# Test with hyphens in the group name
$ ingroup -v wilma systemd-journal
wilma is in group systemd-journal

# If the group does not exist, it's a negative
$ ingroup -v wilma somewronggroup
wilma is not in group somewronggroup