在 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
}
我正在编写一个脚本来将一些文件移动到远程服务器(参见:
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
}