Linux下避免代码重复实现多SSH连接的技术问询
统一多机器SSH连接方式的解决方案
看起来你是想避免在100多条SSH命令里重复写if-else判断,用统一的调用方式来适配两种认证类型对吧?直接用变量赋值失效的问题,大概率是shell解析命令字符串时的空格、特殊字符处理问题,或者变量展开的时机不对。这里给你两个实用的方案,不用挨个修改那100条命令:
方案1:用Shell函数替代变量(最推荐)
函数比变量更灵活,能处理复杂的参数逻辑,调用起来和普通命令完全一样,还能避免字符串解析的坑。
先在脚本最顶部定义这个函数:
sshConnection() { # 根据服务类型返回对应的SSH前缀命令 if [ "${service}" = "Node-Machine" ]; then # 公钥认证的SSH命令模板 echo "ssh ${awsUser}@${fullMachineName}" else # sshpass认证的命令模板,记得提前定义好sshPassword变量 echo "sshpass -p ${sshPassword} ssh -o StrictHostKeyChecking=no ${awsUser}@${fullMachineName}" fi }
之后在需要执行远程命令的地方,直接用$()执行函数,拼接你要跑的命令就行:
# 示例:执行远程磁盘查看命令 $(sshConnection) "df -h" # 示例:用scp上传文件(需要去掉ssh前缀,用sed处理一下) scp local-file.txt $(sshConnection | sed 's/ssh //'):/remote/directory/
方案2:用eval配合变量(谨慎使用)
如果你坚持想用变量来实现,得用eval来强制shell重新解析命令字符串,但要注意变量里的特殊字符(比如密码里的空格、引号)可能会触发意外行为,有一定安全风险。
先在脚本顶部定义变量:
if [ "${service}" = "Node-Machine" ]; then sshConnection="ssh ${awsUser}@${fullMachineName}" else sshConnection="sshpass -p ${sshPassword} ssh -o StrictHostKeyChecking=no ${awsUser}@${fullMachineName}" fi
调用的时候用eval包裹:
eval "${sshConnection} 'df -h'"
额外优化小技巧
如果以后还要加更多机器类型的认证方式,可以把配置做成关联数组,维护起来更方便:
# 提前定义所有机器类型对应的认证模板 declare -A auth_templates=( ["Node-Machine"]="ssh ${awsUser}@${fullMachineName}" ["Web-Machine"]="sshpass -p ${webPassword} ssh -o StrictHostKeyChecking=no ${webUser}@${webMachineName}" ["DB-Machine"]="ssh -i /path/to/db-key.pem ${dbUser}@${dbMachineName}" ) sshConnection() { echo "${auth_templates[${service}]}" }
这样以后新增机器类型,只需要在数组里加一行就行,不用改函数逻辑。
另外建议加个简单的参数检查,比如在函数里判断service、awsUser这些变量有没有被正确赋值,避免因为空值导致命令执行失败。
内容的提问来源于stack exchange,提问作者Jitesh Sojitra
相关产品推荐
相关产品推荐

