在 bash shell 脚本的声明函数中迭代数组

Iterating array in declared function of bash shell script

我一直在努力创建一个脚本来将一些文件从本地计算机移动到远程服务器。作为该过程的一部分,我有一个函数可以直接调用或用 'declare -fp' 包装并发送到 ssh 命令。到目前为止我的代码如下所示:

export REMOTE_HOST=myserver
export TMP=eyerep-files

doTest()
{
    echo "Test moving files from $TMP with arg "
    declare -A files=(["abc"]="123" ["xyz"]="789")
    echo "Files: ${!files[@]}"
    for key in "${!files[@]}"
    do
        echo "$key => ${files[$key]}"
    done
}

moveTest()
{
    echo "attempting move with wrapped function"    
    ssh -t "$REMOTE_HOST" "$(declare -fp doTest|envsubst); doTest ${1@Q}"
}

moveTest 

如果我 运行 脚本带有

./myscript.sh test dev

我得到输出

attempting move with wrapped function
Test moving files from eyerep-files with arg dev
Files: abc xyz
bash: line 7:  => ${files[]}: bad substitution

for 循环的字符串扩展似乎无法正常工作。这是预期的行为吗?如果是这样,是否有另一种循环遍历数组的方法可以避免此问题?

我在这里找到了答案:https://unix.stackexchange.com/questions/294378/replacing-only-specific-variables-with-envsubst/294400

由于我正在导出全局变量,因此我可以使用 compgen 获取它们的列表,并将该列表与 envsubst 一起使用以指定我要替换的变量。我完成的功能最终看起来像:

moveTest()
{
    echo "attempting move with wrapped function"
    ssh -t "$REMOTE_HOST" "$(declare -fp doTest|envsubst "$(compgen -e | awk '[=10=]="${"[=10=]"}"') ''"); doTest ${1@Q}"
}

如果您确信您的远程帐户的默认 shell 是 bash,这可能看起来像:

moveTest() {
    ssh -t "$REMOTE_HOST" "$(declare -f doTest; declare -p $(compgen -e)); doTest ${1@Q}"
}

如果你不是,它可能会是:

moveTest() {
    ssh -t "$REMOTE_HOST" 'exec bash -s' <<EOF
set -- ${@@Q}
$(declare -f doTest; declare -p $(compgen -e))
doTest \"$@\"
EOF
}