1

我正在尝试解析一个 sudoers 文件,该文件包含它自己的正则表达式版本,但无法获得有效且一致的结果。我需要能够将一个变量与另一个包含正则表达式的变量进行比较

Source = "padcl"
Regexp = "*dc*"

尝试的 3 个选项(=~、grep、awk)都不会产生匹配和不匹配所需的结果。

脚本示例

export VAR1="padcl"
export VAR2="*dc*"

if [[ "$VAR1" =~ "$VAR2" ]]
then
        echo "$VAR1 matches $VAR2"
else
        echo "$VAR1 does not match $VAR2"
fi

export VALCNT=`echo "$VAR1" |egrep -E "${VAR2}" |wc -l`
if (( $VALCNT > 0 ))
then
        echo "$VAR1 grep matches $VAR2"
else
        echo "$VAR1 does not grep match $VAR2"
fi

export VALCNT2=`echo "$VAR1" |awk -vparm=${VAR2} '$1 ~ parm {print $0}' |wc -l`
if (( $VALCNT2 > 0 ))
then
        echo "$VAR1 awk matches $VAR2"
else
        echo "$VAR1 does not awk match $VAR2"
fi

输出 - 运行 1(应该匹配)

padcl does not match *dc*
padcl grep matches *dc*
padcl does not awk match *dc*

输出 - 运行 2(不应匹配)

padcl does not match *dx*
padcl grep matches *dx*
padcl does not awk match *dx*

现在我已经编码 20 多年了,我知道 regexp 标准。在不编写自己的正则表达式解析器的情况下,如何使标准下降到 sudoers 支持的更差的正则表达式标准?

解决方案:我发现我可以使用以下命令预解析“ dc ”变量

 export PARM=`echo "$VAR2"| sed 's/\*/\.\*/g'`

这会强制正则表达式查找 1 个或多个字符,而不是 * 指定的 0 个或多个字符。

4

2 回答 2

0

正如@Etan Reisner 在评论中指出的那样,您要匹配的是通配符(或全局)模式,而不是正则表达式。两者之间有很多不同之处,包括:

  • 在 glob 模式中,*匹配任何字符串;在 RE 中,它表示“前面的 0 个或多个”。要匹配 RE 中的任何字符串,请使用.*(0 或更多任何东西)。
  • 说到这,在 RE.中匹配任何单个字符;在全局模式中,它只是一个句点。
  • 要匹配 glob 模式中的任何单个字符,您可以使用?; 在正则表达式中,这意味着“前面的 0 或 1”(即最后一项是可选的,因此\.jpe?g将匹配“.jpg”和“.jpeg”)。
  • 许多 RE 识别器寻找子字符串匹配,而不是整个字符串匹配。因此,grep dc将匹配任何包含“dc”的行。要获取 glob 模式来匹配子字符串,请添加*到模式的开头和结尾;要强制 RE 匹配器查找整个字符串匹配,请添加^到 RE 的开头和$结尾。

...ETC。还有更多的差异,以及 glob 和 RE 语法的许多变化。在它们之间进行翻译是可能的,但通常不值得。特别是在这种情况下,由于 bash 具有内置的 glob 匹配功能:

VAR1="padcl"
VAR2="*dc*"

if [[ "$VAR1" = $VAR2 ]]; then
    echo "$VAR1 matches $VAR2"
else
    echo "$VAR1 does not match $VAR2"
fi

请注意,您必须使用 bash(不是通用 POSIX shell),因此请使用#!/bin/bashNOT启动脚本#!/bin/sh。这是因为这种匹配功能仅在 中可用,在[[ ]]中不可用[ ],并且其他一些 POSIX shell 不支持[[ ]]. 此外,重要的是$VAR2不要在这种情况下被双引号;如果它是双引号,则 bash 将寻找文字匹配而不是模式匹配(请注意,这是您的 shell 测试未按预期运行的部分原因)。

最后,bash 的 glob 语法可能与 sudo 的不太一样。如果这是出于安全关键目的(与 /etc/sudoers 相关的任何内容往往是),您可能必须编写自己的识别器才能正确匹配 sudo。

于 2014-12-01T02:18:46.990 回答
0

我正在使用 #!/bin/bash shell 命令,我没有在帖子中包含它。

我发现我可以使用以下命令预解析“dc”变量

   export PARM=`echo "$VAR2"| sed 's/\*/\.\*/g'`

这会强制正则表达式查找 1 个或多个字符,而不是 * 指定的 0 个或多个字符。感谢您对发布协议的反馈和建议。

于 2014-12-02T01:03:51.337 回答