You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solaris 11.4下Expect脚本实现SSH密钥已安装检测的技术问询

我来帮你解决这个问题——在Solaris 11.4上用Expect脚本实现SSH公钥自动部署,并且跳过已经存在密钥的服务器。你的核心痛点是没法正确识别"无密码登录成功"的状态,之前匹配空字符串的思路确实会导致误匹配,下面给你一套完整的解决方案:

核心思路调整

与其先尝试部署再判断,不如先验证目标服务器是否已经接受公钥:发起一个无密码SSH请求,执行一个简单的测试命令(比如输出一段标识文本)。如果能成功执行,说明密钥已存在,直接跳过;如果遇到密码提示/主机密钥确认,再执行密钥部署操作。

修改后的完整脚本

#!/usr/bin/expect
set timeout 1200
set user [lindex $argv 0]
set host [lindex $argv 1]
set pass [lindex $argv 2]

# 读取本地公钥并去除末尾换行符,避免写入时产生多余空行
set sshkeyfile [open ~/.ssh/id_rsa.pub r]
set sshid [string trimright [read $sshkeyfile] "\n"]
close $sshkeyfile

# 第一步:尝试无密码登录,验证密钥是否已配置
spawn ssh $user@$host "echo 'KEY_VERIFIED_SUCCESS'"
expect {
    # 处理首次登录的主机密钥确认提示
    "continue connecting (yes/no/[a-zA-Z0-9:]+)?" {
        send "yes\r"
        exp_continue
    }
    # 出现密码提示:说明密钥未配置,需要部署
    "Password:" {
        # 中断当前无效的SSH会话(发送Ctrl+C)
        send "\003"
        expect eof

        # 执行密钥部署命令:先检查密钥是否已存在,不存在再追加
        spawn ssh $user@$host "mkdir -m 700 ~/.ssh 2>/dev/null; grep -q '$sshid' ~/.ssh/authorized_keys 2>/dev/null || echo '$sshid' >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys"
        expect {
            "continue connecting (yes/no/[a-zA-Z0-9:]+)?" {
                send "yes\r"
                exp_continue
            }
            "Password:" {
                send "$pass\r"
                expect eof
                puts "✅ Successfully deployed key to $host"
            }
            timeout {
                puts "❌ Timeout when deploying key to $host"
                exit 1
            }
        }
    }
    # 成功获取测试输出:说明密钥已存在,直接跳过
    "KEY_VERIFIED_SUCCESS" {
        expect eof
        puts "ℹ️ Key already exists on $host, skipping"
        exit 0
    }
    # 错误处理:超时或意外断开连接
    timeout {
        puts "❌ Timeout connecting to $host"
        exit 1
    }
    eof {
        puts "❌ Unexpected connection closed to $host"
        exit 1
    }
}

关键细节说明

  1. 精准匹配登录成功状态:用自定义的KEY_VERIFIED_SUCCESS输出作为登录成功的标识,完全避免了空字符串匹配的误判问题。
  2. 双重校验避免重复写入:部署密钥时,通过grep -q '$sshid' ~/.ssh/authorized_keys先检查密钥是否已存在,只有不存在时才追加写入,进一步确保幂等性。
  3. 健壮的会话管理:遇到密码提示时,先发送Ctrl+C中断当前会话,再启动新的部署会话,避免残留无效进程。
  4. 友好的状态提示:用✅/ℹ️/❌区分不同操作结果,批量部署时更容易排查问题。

调试技巧

如果脚本运行不符合预期,可以用Expect的调试模式查看匹配过程:

expect -d your_script.exp username target_host password

内容的提问来源于stack exchange,提问作者AndyM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:15:47