我正在编写一个脚本,将一些文件移动到远程服务器(请参阅:函数调用(有关更多详细信息,请参阅unix shell脚本的Here文档(。为了让脚本既能在本地机器上工作,也能在远程服务器上工作,我使用"declare-f"来包装要远程执行的现有函数。到目前为止,我已经想出了这个:
myscript.sh
REMOTE_HOST=myhost
TMP=eyerep-files
getMoveCommand()
{
echo Src Dir: $2
sudo cp ~/$TMP/start.ini ~/$1/start_b.ini
ls ~/$2
echo Target Dir: $1
ls ~/$1
}
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 "$1" in
# remote deploy
remote)
moveRemote $2
;;
# local deploy
local)
getMoveCommand $2
;;
*)
echo "Usage: myscript.sh {local|remote}"
exit 1
;;
esac
}
moveFiles $1 $2
exit 0
如果使用"调用/myscript.shremote-dev'脚本应该ssh到远程服务器,并将文件从一个文件夹移动到另一个文件夹。我遇到的问题是字符串替换。我有一堆全局变量作为getMoveCommand需要访问的常量。在这里的例子中只有一个(TMP(,所以我可以简单地将其作为参数传递。然而,在实际的脚本中,所做的工作更为复杂,需要传递的参数数量会使该解决方案变得难以处理。由于这些变量永远不会改变,所以在将封装的函数发送到ssh之前,似乎应该可以强制进行字符串替换。
我想做的事情可能吗?如果可能,怎么做?如果没有,是否有其他方法可以处理此问题,而不需要向函数传递大量参数?
如果导出变量,则可以使用envsubst:
export TMP=foo
getMoveCommand() {
echo TMP is $TMP
}
declare -fp getMoveCommand|envsubst
上面的脚本打印:
getMoveCommand ()
{
echo TMP is foo
}
您也可以使用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}"