bash - 如何防止 BASH_REMATCH 泄漏出函数?

标签 bash memory-leaks

我想使用 bash 运算符 +~ 首先拆分一个字符串,然后再次检查生成的字符串。当我尝试这个时,如果发现 BASH_REMATCH 的元素被第二次使用覆盖,所以 mother-function 在第二次使用时失败。

以下面构造的例子为例:

#!/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 覆盖的。

$ 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(请参见下面的示例)。这是明智的做法吗?还是有更好的方法来防止 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 ./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

最佳答案

有点 hack,但由于它仅在当前 shell 中是本地的,因此您可以在函数中运行子 shell。

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

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

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

除此之外,我认为将它分配给另一个数组是您将获得的最好结果(实际上比这个更好,因为它不会打开新的进程/子 shell)。

关于bash - 如何防止 BASH_REMATCH 泄漏出函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37674871/

相关文章:

node.js - Redis 使用 node.js 占用内存

java - Java中的突发内存使用

bash - 为什么/bin/kill 的有效信号与 kill 不同?

c++ - 非常奇怪的内存泄漏

c# - ListCollectionView 是否泄漏内存?

bash - 比较不区分大小写的字符串,然后计算重复项

c# - 使用它的指针从托管 C# 中释放非托管内存

linux - Bash ,根据带有数字和字符串的文件名列出文件

linux - 从 bash 将特定的十六进制模式写入文件

用于禁用 root 登录的 Bash 脚本