如何防止bash_rematch泄漏出功能? 我想使用bash操作员 +〜首先拆分字符串,然后再次检查结果字符串。如果发现Bash_rematch的元素被第二个

问题描述 投票:0回答:2
的元素被第二次用法覆盖,所以母亲功能在第二次使用时失败。 例如,例如以下构造的示例:

#!/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
(请参见下面的示例)。这是这样做的聪明方法,还是有一种更好的方法来防止从功能中泄漏出来?

thiscode

$ 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

hack的位置,但由于它仅是当前外壳的本地,您可以在函数中运行一个子壳。

BASH_REMATCH



#!/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
这将使BASH_REMATCH始于全局到两个函数。 除此之外,我认为将其分配给另一个阵列是您将要获得的最好的(因为它没有打开新的过程/子壳)。

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
是一个可读的变量,因此诸如

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

not
之类的东西可以工作。
bash memory-leaks
2个回答
3
投票

( checkNum ${BASH_REMATCH[1]} checkNum ${BASH_REMATCH[2]} )

在您的情况下 - 只是提及 - 您可以使用:

BASH_REMATCH


我知道这很古老,但是我本人遇到了同样的问题,进行了一些谷歌搜索并遇到了此页。安德烈亚斯(Andreas)关于bash_rematch仅阅读的建议使我找到了解决方案。

Bash_rematch

是不读取:


1
投票

但它是全局的,因此对其进行修改的函数调用可能会引起混乱。但是您可以使用局部变量来保存bash_rematch,然后调用

local re
re=("${BASH_REMATCH[@]}")
,然后在此简化示例中还原bash_rematch,如:
# teststring="1234,5678"
checkNum "${teststring%%,*}" # 1234
checkNum "${teststring#*,}"  # 5678

    
	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.