我有一个服务器正在运行,我使用 php 运行 bash 脚本来验证用户的某些信息。例如,我设置了一个虚拟主机服务器,为了能够向他们的帐户添加另一个域,我想验证用户是否实际上是“客户”组的成员。最好的方法是什么?
我搜索了谷歌,但它所提供的只是检查用户或组是否存在的方法,所以谷歌现在没有太大的帮助。
我有一个服务器正在运行,我使用 php 运行 bash 脚本来验证用户的某些信息。例如,我设置了一个虚拟主机服务器,为了能够向他们的帐户添加另一个域,我想验证用户是否实际上是“客户”组的成员。最好的方法是什么?
我搜索了谷歌,但它所提供的只是检查用户或组是否存在的方法,所以谷歌现在没有太大的帮助。
if id -nG "$USER" | grep -qw "$GROUP"; then
echo $USER belongs to $GROUP
else
echo $USER does not belong to $GROUP
fi
解释:
id -nG $USER
显示用户所属的组名。grep -qw $GROUP
静默检查 $GROUP 作为一个整体是否存在于输入中。尝试这样做:
username=ANY_USERNAME
if getent group customers | grep -q "\b${username}\b"; then
echo true
else
echo false
fi
或者
username=ANY_USERNAME
if groups $username | grep -q '\bcustomers\b'; then
echo true
else
echo false
fi
使用零字符分隔的固定字符串 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
我知道这可能是旧线程,但以防万一这也很好用:
id -Gn "username"|grep -c "groupname"
如果返回任何数字 > 0,则用户是该组的成员。
你可以使用
groups $username_here | grep -q '\busergroup\b'
如果找到匹配项,则退出代码将为 0,如果未找到匹配项,则为 1。
user_in_group()
{
groups $1 | grep -q "\b$2\b"
}
您可以将此功能用作user_in_group userfoo groupbar
对于所有那些高尔夫球迷:
ingroup(){ [[ " `id -Gn $2` " == *" $1 "* ]]; }
用法:ingroup group [user]
例子:
if ingroup video; then
echo 'Enjoy the show!'
fi
TL;DR 关键是我利用了内置的通配符来查找子字符串。
编辑:感谢@Anthony Geoghegan的id -Gn
提示。
使用零分隔符按行分割:
id -nGz user | tr '\0' '\n' | grep '^group$'
前段时间,我写了一个 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’
尚未针对组或用户名称中包含空格或其他不寻常字符的情况进行测试,但一些研究表明此类名称不合法:组名称的 POSIX 基本定义指出
为了在符合标准的系统中可移植,该值由可移植文件名字符集中的字符组成。
可移植文件名字符集指定为字母数字字符 AZ、az、0-9 以及句点、下划线和连字符减号。
听起来像另一个答案:
username='myuser'
if grep -q -E "^customers:.*[:,]$username(,.*|\b)" /etc/group; then
echo 'true'
else
echo 'false'
fi
正如命令sputnick
输出所报告的,groups
可能取决于您的操作系统。我不确定这段代码将如何执行,但很可能它会做得更好。
我的版本不依赖 grep。
第一个参数(必填):group
第二个参数(可选,默认为当前用户)
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"
}
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'
Bash 单行:
[[ " $(groups) " =~ ' spark ' ]] && echo 'Is in group'
Bash 多行:
if [[ " $(groups) " =~ ' spark ' ]]; then
echo 'Is in group'
fi
这是我的。
#!/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