使用Python实现SSH自动登录服务器,如何解决密码自动输入失败问题
问题根因
你的代码存在三个核心错误:
- 直接对比
subprocess.Popen进程对象和字符串,完全没有读取进程的实际输出,判断逻辑永远不成立 - SSH默认将密码提示输出到伪终端(PTY)而非标准输出流,常规的subprocess管道既捕获不到提示,也无法正常写入密码
- 写入密码时没有添加换行符,等于输入密码后没有按下回车,SSH会一直等待输入最终返回验证失败
解决方案
方案1:使用pexpect实现(最简单稳定)
pexpect是专门用来处理交互式进程的第三方库,原生支持伪终端分配,可以直接匹配输出提示并输入内容。
首先安装依赖:
pip install pexpect
示例代码:
import pexpect server_ip = "server" password = "your_password" # 发起SSH连接 child = pexpect.spawn(f"ssh root@{server_ip}") # 匹配密码提示 child.expect("root@.*'s password:") # 输入密码加换行 child.sendline(password) # 后续可以继续匹配登录后的提示符执行其他命令,比如匹配#提示符 child.expect("#") # 执行示例命令 child.sendline("ls -la") # 打印命令输出 print(child.before.decode()) # 退出连接 child.sendline("exit") child.wait()
方案2:使用sshpass配合subprocess(无需额外Python依赖,需要系统安装sshpass)
首先在系统上安装sshpass:
# Debian/Ubuntu apt install sshpass # CentOS/RHEL yum install sshpass
然后直接调用即可,不需要处理交互逻辑:
import subprocess server_ip = "server" password = "your_password" # 直接通过sshpass传递密码执行SSH命令,示例执行hostname命令 result = subprocess.run( ["sshpass", "-p", password, "ssh", "-o", "StrictHostKeyChecking=no", f"root@{server_ip}", "hostname"], capture_output=True, text=True ) print(result.stdout)
注意:sshpass会明文传递密码,仅在测试环境或可信内网环境使用,生产环境不推荐。
最优方案:配置SSH公钥免密登录
无需任何密码传递逻辑,安全性最高,操作步骤:
- 本地生成密钥对:
ssh-keygen -t rsa,一路回车即可 - 将公钥上传到服务器:
ssh-copy-id root@server - 之后不需要输入密码就可以直接登录,subprocess调用SSH命令也不需要处理任何交互逻辑。
内容的提问来源于stack exchange,提问作者gggg
相关产品推荐
相关产品推荐

