如何通过SSH执行包含变量的Bash脚本?
解决方案
给你几个可行的方案,按需选择:
方案1:用envsubst预处理脚本(推荐)
这是最简洁可靠的方式,envsubst会自动把脚本里的环境变量替换成本地的实际值,再传给远程执行。
在main.sh里先定义并导出需要的变量,再执行以下命令:
# main.sh中定义并导出变量 export dir1="/path/to/source" export dir2="/path/to/target" # 预处理sub.sh并通过SSH执行 envsubst < ./sub.sh | ssh $user@$ip
如果只想替换特定变量(避免意外替换脚本里其他类似格式的字符串),可以指定变量名:
envsubst '$dir1 $dir2' < ./sub.sh | ssh $user@$ip
注意:envsubst属于gettext工具集,大部分Linux发行版默认安装,若未安装可通过包管理器添加(如apt install gettext或yum install gettext)。
方案2:本地展开脚本内容后传递给远程
直接在本地把sub.sh的内容展开变量,再作为命令字符串传给远程SSH执行:
# main.sh中定义变量 dir1="/path/to/source" dir2="/path/to/target" # 读取sub.sh内容,展开变量后传给远程 ssh $user@$ip "$(cat ./sub.sh | envsubst)"
这种方式和方案1原理类似,只是把预处理后的脚本内容作为整体字符串传给远程执行,适合需要一次性传递的场景。
方案3:用sed手动替换变量(兼容无envsubst的环境)
如果系统没有envsubst,可以用sed手动替换脚本里的变量:
# main.sh中定义变量 dir1="/path/to/source" dir2="/path/to/target" # 替换变量后传给远程(转义变量中的/避免冲突) sed -e "s/\$dir1/${dir1//\//\\/}/g" -e "s/\$dir2/${dir2//\//\\/}/g" ./sub.sh | ssh $user@$ip
注意:这里的${dir1//\//\\/}是为了转义变量中的/,避免和sed的分隔符冲突。如果变量里还有其他特殊字符(如&、*),需要额外处理,所以该方案仅适合变量内容简单的场景。
内容的提问来源于stack exchange,提问作者Giang Phạm
相关产品推荐
相关产品推荐

