如何使用Paramiko向主机发送用户输入以完成Linux服务器初始化
解决Paramiko连接时交互式修改过期密码的问题
你的问题核心是exec_command仅适用于执行非交互式的单个Linux命令,而首次连接时的密码修改属于需要实时响应的终端交互场景,因此得用Paramiko的invoke_shell()方法建立交互式shell会话,模拟手动输入的流程。
解决方案要点
- 用
invoke_shell()替代exec_command,创建持续的终端会话 - 等待终端输出指定提示后,发送新密码(必须加换行符
\n模拟回车确认) - 处理第二次密码确认的提示,重复发送新密码
- 通过检测输出内容判断交互节点,避免硬编码等待时间导致时序错误
修改后的代码示例
import paramiko import time ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器,此处用密钥登录,也可替换为password参数 ssh.connect('my_host', username='admin', key_filename='你的私钥路径') # 初始化交互式shell会话 shell = ssh.invoke_shell() shell.settimeout(10) # 设置超时,防止无限等待 # 等待并响应首次密码输入提示 while True: if shell.recv_ready(): output = shell.recv(1024).decode('utf-8') print(output) if "New password:" in output: shell.send('NewPassword\n') break time.sleep(0.5) # 等待并响应第二次密码确认提示 while True: if shell.recv_ready(): output = shell.recv(1024).decode('utf-8') print(output) # 根据实际系统提示调整判断条件,比如部分系统是"Retype new password:" if "Retype new password:" in output or "New password:" in output: shell.send('NewPassword\n') break time.sleep(0.5) # 等待操作完成,输出最终结果 time.sleep(2) if shell.recv_ready(): final_output = shell.recv(1024).decode('utf-8') print(final_output) ssh.close()
关键细节说明
invoke_shell()创建的会话和手动SSH终端完全一致,支持所有交互式操作- 必须发送
\n换行符,终端需要回车才能识别输入完成 - 用
recv_ready()检测新输出,比固定sleep更可靠,适配不同服务器的响应速度 - 不同系统的提示文本可能有差异,需根据实际终端输出调整判断字符串
内容的提问来源于stack exchange,提问作者cypherlock1010
相关产品推荐
相关产品推荐

