Arrays 直接调用bash中的数组内容是正常的,但从函数调用时丢失

Arrays 直接调用bash中的数组内容是正常的,但从函数调用时丢失,arrays,bash,shell,loops,ifs,xmlstarlet,Arrays,Bash,Shell,Loops,Ifs,Xmlstarlet,我试图使用xmllint搜索xml文件并将所需的值存储到数组中。以下是我正在做的: #!/bin/sh function getProfilePaths { unset profilePaths unset profilePathsArr profilePaths=$(echo 'cat //profiles/profile/@path' | xmllint --shell file.xml | grep '=' | grep -v ">" | cut -f 2

我试图使用xmllint搜索xml文件并将所需的值存储到数组中。以下是我正在做的:

#!/bin/sh

function getProfilePaths {
    unset profilePaths
    unset profilePathsArr
    profilePaths=$(echo 'cat //profiles/profile/@path' | xmllint --shell file.xml | grep '=' | grep -v ">" | cut -f 2 -d "=" | tr -d \")
    profilePathsArr+=( $(echo $profilePaths))
    return 0
}
在另一个功能中,我有:

function useProfilePaths {
    getProfilePaths
    for i in ${profilePathsArr[@]}; do
    echo $i
    done
    return 0
}

useProfilePaths
无论是在命令行手动执行命令,还是作为包装器脚本的一部分从不同的函数调用命令,函数的行为都会发生变化。当我可以从包装器脚本调用函数时,数组中的项是1,而当我从命令行调用函数时,数组中的项是2:

$ echo ${#profilePathsArr[@]}
2
ProfilePath的内容在回显时如下所示:

$ echo ${profilePaths}
/Profile/Path/1 /Profile/Path/2
我不确定xmllint调用的分隔符是什么

当我从包装器脚本调用函数时,for循环的第一次迭代的内容如下所示:

for i in ${profilePathsArr[@]}; do
    echo $i
done
第一个回声看起来像:

/Profile/Path/1
/Profile/Path/2
。。。第二个回声是空的

有人能帮我调试这个问题吗?如果我能找出xmllint使用的分隔符是什么,也许我能正确地解析数组中的项

仅供参考,我已经尝试了以下方法,结果相同:

profilePaths=($(echo 'cat //profiles/profile/@path' | xmllint --shell file.xml | grep '=' | grep -v ">" | cut -f 2 -d "=" | tr -d \"))

您应该使用适当的
--xpath
开关,而不是使用
--shell
开关和许多管道

但据我所知,当你有多个值时,没有简单的方法来分割不同的节点

所以一个解决方案是像这样迭代:

profilePaths=(
    $(
        for i in {1..100}; do
            xmllint --xpath "//profiles[$i]/profile/@path" file.xml || break
        done
    )
)
或使用:


默认情况下,它使用换行符显示输出

您遇到的问题与数据封装有关;具体地说,函数中定义的变量是局部变量,因此除非另行定义,否则无法在该函数外部访问它们


根据您正在使用的
sh
的实现情况,您可以通过在变量定义上使用
eval
或使用
global
等修饰符来解决此问题,如
mksh
zsh
bash
。我知道
mksh
的实现确实有效。

感谢您提供有关如何解决此问题的反馈。经过进一步研究,我改变了迭代“profilePaths”变量内容的方式,将其值插入到“profilePathsArr”数组中,从而实现了这一点:

# Retrieve the profile paths from file.xml and assign to 'profilePaths'
profilePaths=$(echo 'cat //profiles/profile/@path' | xmllint --shell file.xml | grep '=' | grep -v ">" | cut -f 2 -d "=" | tr -d \")

# Insert them into the array 'profilePathsArr'
IFS=$'\n' read -rd '' -a profilePathsArr <<<"$profilePaths"
#从file.xml检索配置文件路径并分配给“profilepath”
ProfilePath=$(echo'cat//profiles/profile/@path'| xmllint--shell file.xml | grep'='| grep-v“>“| cut-f2-d”=“| tr-d\”)
#将它们插入数组“profilePathsArr”

IFS=$'\n'read-rd'-a profilePathsArr这里出了什么问题?循环确实在两个数组元素上迭代。请发布一个不引用本地文件的完整脚本(以便我们可以在计算机上运行),并清楚地解释为什么输出是意外的。
# Retrieve the profile paths from file.xml and assign to 'profilePaths'
profilePaths=$(echo 'cat //profiles/profile/@path' | xmllint --shell file.xml | grep '=' | grep -v ">" | cut -f 2 -d "=" | tr -d \")

# Insert them into the array 'profilePathsArr'
IFS=$'\n' read -rd '' -a profilePathsArr <<<"$profilePaths"