使用Paramiko实现SSH远程切换root并执行命令的问题求助
解决Paramiko SSH切换Root的交互式命令执行问题
问题根源
sudo: no tty present and no askpass program specified:sudo默认要求终端(tty)完成身份验证,管道传递密码的方式不符合其安全机制;且exec_command每次调用都是独立SSH会话,即便切换root成功,后续命令仍在普通用户环境执行。- 加
get_pty=True后无限运行:sudo su-会启动新的root shell,此时stdout不会主动终止,程序持续阻塞等待输出。
正确解决方案
使用invoke_shell()创建持久化交互式shell会话,在同一个shell中模拟手动操作流程,依次执行命令:
import paramiko import time # 配置信息 host = "你的服务器IP" username = "普通用户名" password = "普通用户密码" root_password = "Root密码" # 初始化SSH客户端 client = paramiko.client.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(host, username=username, password=password, timeout=10) # 创建交互式shell shell = client.invoke_shell() shell.settimeout(10) # 等待shell初始化 time.sleep(1) # 执行命令1:ls shell.send("ls\n") time.sleep(2) # 读取并打印输出 output = shell.recv(65535).decode() print("=== ls 输出 ===") print(output) # 执行命令2:切换到root shell.send("sudo su-\n") time.sleep(1) # 读取sudo的密码提示,确认需要输入密码 prompt_output = shell.recv(65535).decode() if "[sudo] password for" in prompt_output: shell.send(f"{root_password}\n") time.sleep(2) # 读取切换后的输出 root_output = shell.recv(65535).decode() print("\n=== 切换Root输出 ===") print(root_output) # 执行命令3:验证当前用户身份 shell.send("id\n") time.sleep(2) id_output = shell.recv(65535).decode() print("\n=== 当前用户信息 ===") print(id_output) # 关闭连接 client.close()
关键注意事项
- 用
invoke_shell()替代exec_command,确保所有命令在同一个shell会话执行,切换root后的环境可被后续命令继承。 - 发送命令时必须追加换行符
\n,模拟手动回车操作。 - 根据服务器响应速度调整
time.sleep()时长,避免因命令未执行完成就读取输出导致内容缺失。 - 可通过判断输出中的特定字符串(如密码提示)动态触发操作,比固定sleep更可靠(可自行扩展逻辑)。
内容的提问来源于stack exchange,提问作者mrin9san
相关产品推荐
相关产品推荐

