在 shell 脚本的声明函数中强制替换字符串

Forcing string replacement in declared function of shell script

我正在编写一个脚本来将一些文件移动到远程服务器(参见: 了解更多详情)。为了允许脚本在本地机器和远程服务器上工作,我使用 'declare -f' 包装现有函数以远程执行。到目前为止,我想出了这个:

myscript.sh

REMOTE_HOST=myhost
TMP=eyerep-files

getMoveCommand()
{
    echo Src Dir: 
    sudo cp ~/$TMP/start.ini ~//start_b.ini
    
    ls ~/
    echo Target Dir: 
    ls ~/
}

moveRemote()
{
    echo "attempting move with here doc"
    echo $(declare -fp getMoveCommand ) 
    ssh -t "$REMOTE_HOST" "$(declare -fp getMoveCommand); getMoveCommand ${1@Q} ${TMP@Q}"
}

moveFiles()
{   
        case "" in
      # remote deploy
      remote)
        moveRemote 
        ;;
      # local deploy
      local)
        getMoveCommand 
        ;;
      *)
        echo "Usage: myscript.sh {local|remote}"
        exit 1
        ;;
    esac
    
}

moveFiles  
exit 0

如果使用“./myscript.sh remote dev”调用,脚本应该通过 ssh 连接到远程服务器并将文件从一个文件夹移动到另一个文件夹。我 运行 遇到的问题是字符串替换。我有一堆全局变量充当 getMoveCommand 需要访问的常量。在此处的示例中,只有一个 (TMP),因此我可以简单地将其作为参数传递。然而,在实际脚本中,所做的工作更加复杂,而且需要传入的参数数量会使该解决方案变得笨拙。由于这些变量永远不会改变,似乎应该可以在将包装函数发送到 ssh 之前强制进行字符串替换。

我想做的事可行吗?如果可行,怎么做?如果没有,是否有另一种不需要向函数传递大量参数的方法来处理这个问题?

您还可以使用 declare -p:

发送全局变量
ssh -t "$REMOTE_HOST" "$(declare -fp getMoveCommand; declare -p GLOBAL_VAR_1 GLOBAL_VAR_2)"$'\n'"getMoveCommand ${1@Q} ${TMP@Q}"

您还可以使用另一个声明它们的全局变量,以便轻松扩展它们:

GLOBAL_VARS=(GLOBAL_VAR_1 GLOBAL_VAR_2)
...
ssh -t "$REMOTE_HOST" "$(declare -fp getMoveCommand; declare -p "${GLOBAL_VARS[@]}")"$'\n'"getMoveCommand ${1@Q} ${TMP@Q}"

如果你的变量有共同的前缀,你也可以通过"${!PREFIX@}"扩展它们。无需存储到变量。

或者也可以创建一个“导出”功能以保持内容更简洁:

dump_env() {
    declare -fp getMoveCommand
    declare -p GLOBAL_VAR_1 GLOBAL_VAR_2
}
...
ssh -t "$REMOTE_HOST" "$(dump_env)"$'\n'"getMoveCommand ${1@Q} ${TMP@Q}"

如果导出变量,则可以使用 envsubst:

export TMP=foo

getMoveCommand() {
        echo TMP is $TMP
}

declare -fp getMoveCommand|envsubst

上面的脚本打印:

getMoveCommand () 
{ 
    echo TMP is foo
}