首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止BASH_REMATCH从函数中泄漏?

如何防止BASH_REMATCH从函数中泄漏?
EN

Stack Overflow用户
提问于 2016-06-07 08:59:41
回答 2查看 339关注 0票数 3

我想使用bash操作符+~首先拆分一个字符串,然后再次检查得到的字符串。当我尝试这样做时,如果发现BASH_REMATCH的元素被第二种用法覆盖,那么母函数在第二次使用时就会失败。

例如,以下构造的示例:

代码语言:javascript
复制
#!/bin/bash

inputline="abc123ABC123abc,xyz890XYZ890xyz"

checkABC ()
{
    local teststring="$1"
    local pattern="([^,]+),(.*)"

    if [[ $teststring =~ $pattern ]]; then
        echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
        checkNum ${BASH_REMATCH[1]}
        checkNum ${BASH_REMATCH[2]}
    fi

}

checkNum ()
{
    if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
        echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
    fi
}

set -x
checkABC $inputline

这将给出以下输出,我们可以看到${BASH_REMATCH[2]}是如何被函数checkNum覆盖的。

代码语言:javascript
复制
$ bash ./leaking.sh
+ checkABC abc123ABC123abc,xyz890XYZ890xyz
+ local teststring=abc123ABC123abc,xyz890XYZ890xyz
+ local 'pattern=([^,]+),(.*)'
+ [[ abc123ABC123abc,xyz890XYZ890xyz =~ ([^,]+),(.*) ]]
+ echo 'abc123ABC123abc; xyz890XYZ890xyz'
abc123ABC123abc; xyz890XYZ890xyz
+ checkNum abc123ABC123abc
+ [[ abc123ABC123abc =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '123; 123'
123; 123
+ checkNum 123
+ [[ 123 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]

我知道,我可以通过将重匹配的结果复制到另一个数组来防止这种情况,我可以在这个数组上进行本地处理并应用checkNum (参见下面的示例)。这是一种智能的方法吗,还是有更好的方法来防止从函数中泄漏?

这段代码

代码语言:javascript
复制
#!/bin/bash

inputline="abc123ABC123abc,xyz890XYZ890xyz"

checkABC ()
{
    local teststring="$1"
    local pattern="([^,]+),(.*)"
    local -a storeRematch

    if [[ $teststring =~ $pattern ]]; then
        storeRematch=("${BASH_REMATCH[@]}")
        echo "${storeRematch[1]}; ${storeRematch[2]}"
        checkNum ${storeRematch[1]}
        checkNum ${storeRematch[2]}
    fi

}

checkNum ()
{
    if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
        echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
    fi
}

set -x
checkABC $inputline

按我希望的方式执行:

代码语言:javascript
复制
bash ./notleaking.sh
+ checkABC abc123ABC123abc,xyz890XYZ890xyz
+ local teststring=abc123ABC123abc,xyz890XYZ890xyz
+ local 'pattern=([^,]+),(.*)'
+ local -a storeRematch
+ [[ abc123ABC123abc,xyz890XYZ890xyz =~ ([^,]+),(.*) ]]
+ storeRematch=("${BASH_REMATCH[@]}")
+ echo 'abc123ABC123abc; xyz890XYZ890xyz'
abc123ABC123abc; xyz890XYZ890xyz
+ checkNum abc123ABC123abc
+ [[ abc123ABC123abc =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '123; 123'
123; 123
+ checkNum xyz890XYZ890xyz
+ [[ xyz890XYZ890xyz =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '890; 890'
890; 890
EN

回答 2

Stack Overflow用户

发布于 2016-06-07 09:24:21

有点麻烦,但由于它只是当前shell的本地版本,所以您可以在函数中运行子shell。

代码语言:javascript
复制
checkNum ()
{
(
    if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
        echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
    fi
)
}

代码语言:javascript
复制
(
 checkNum ${BASH_REMATCH[1]}
 checkNum ${BASH_REMATCH[2]}
)

这将防止BASH_REMATCH对这两个函数都是全局的。

除此之外,我认为将它分配给另一个数组是最好的(事实上,它不会打开一个新的进程/子subshell)。

票数 3
EN

Stack Overflow用户

发布于 2016-06-07 09:20:55

BASH_REMATCH是一个只读变量,所以像local BASH_REMATCH这样的东西不能工作。

根据您的建议,您可以将结果复制到另一个变量:

代码语言:javascript
复制
local re
re=("${BASH_REMATCH[@]}")

在你的例子中--我想提一提--你可以用:

代码语言:javascript
复制
# teststring="1234,5678"
checkNum "${teststring%%,*}" # 1234
checkNum "${teststring#*,}"  # 5678
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37674871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档