bash 正则表达式匹配在 [[ ]] 中失败

bash 正则表达式匹配在 [[ ]] 中失败

我想通过以下方式检查用户是否属于某个组

[[ "$(getent group groupname)" =~ \busername\b ]]

但这不起作用(bash 5.0.3),尽管以下方法有效:

getent group groupname | grep -E "\busername\b"

我注意到反斜杠似乎在某个地方被吞掉了

bash -cx '[[ "$(getent group groupname)" =~ \busername\b ]]'
++ getent group groupname
+ [[ groupname:x:24:username =~ busernameb ]]

但这也可能是 的影响-x

任何人都可以澄清这一点吗? :-)

答案1

bash,中\是一个引用运算符,如'and "。所以:

[[ "$(getent group groupname)" =~ \busername\b ]]

是相同的:

[[ "$(getent group groupname)" =~ 'b'username'b' ]]

bash3.2 开始,bash 确保当您在正则表达式中引用一个字符时,如果它有一个字符,它会删除其作为正则表达式运算符的特殊含义(这不是 的情况b)。

bash3.1 中,您可以执行以下操作:

[[ "$(getent group groupname)" =~ '\busername\b' ]]

如果您打开该bash31选项或设置$BASH_COMPAT为,您仍然可以这样做3.1。这也适用于zsh.

这将适用于系统扩展正则表达式库支持\b非标准扩展的系统(例如最近的 GNU 系统)。

在 bash 3.2 及更高版本中,这不起作用,因为通过引用\,bash 消除了作为正则表达式运算符的特殊性\(实际上它使用\\busername\\b.

你可以做的就是写它:

regexp='\<username\>' # here using the slightly more portable \< \> instead of \b
[[ "$(getent group groupname)" =~ $regexp ]] # make sure $regexp is *not* quoted

然后它可以与 bash 3.1 和 bash 3.2+(以及 zsh 和 ksh93)一起使用。看将正则表达式存储在 shell 变量中如何避免引用 shell 特有字符的问题?了解更多详情。

但在这里,我将使用标准sh语法并执行以下操作:

group=groupname
user=username

group_definition=$(getent -- group "$group") || exit
case ,${group_definition##*:}, in
  (*,"$user",*) printf '%s\n' "$user is in the $group group\n"
esac

如果用户名包含正则表达式运算符(.在用户名中很常见)或者用户名恰好与组名相同,那么它也会更可靠地工作。

相关内容