使用Paramiko以sudo权限执行Linux命令、传密码及批量执行的相关问题
Paramiko 以sudo权限执行命令问题解决方案
原代码无输出的原因
你提供的代码无法正常运行的核心原因是:默认配置下sudo会从交互式TTY读取密码,而exec_command默认创建非交互式无TTY会话,sudo不会识别你写入stdin的密码。你缺少了sudo的-S参数,该参数的作用是指定sudo从标准输入读取密码。
第二个问题解答
你提到的「无法先执行sudo -s,之后在同个非root启动的会话中以root身份执行后续命令」的认知是错误的。只要使用Paramiko的交互式Shell通道(invoke_shell())而非单条执行的exec_command,就可以维持会话状态:开启sudo -s并输入密码后,后续所有命令都会默认以root身份执行;即使不切换root shell,同一会话内sudo在默认缓存超时时间(通常为5分钟)内也不需要重复输入密码。
可用代码示例
1. 单条sudo命令执行(传入密码+获取输出)
import paramiko # 初始化SSH客户端 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接主机,替换为实际主机信息即可 ssh.connect(hostname='主机IP', port=22, username='普通用户名', password='普通用户密码') sudo_password = "你的sudo密码" command = "ls -l /root" # 加-S参数让sudo从stdin读密码 stdin, stdout, stderr = ssh.exec_command(f"sudo -S {command}") # 写入密码 stdin.write(f"{sudo_password}\n") stdin.flush() # 读取输出和错误信息 output = stdout.read().decode().splitlines() error = stderr.read().decode().splitlines() print("命令输出:") for line in output: print(line) if error: print("错误信息:") for line in error: print(line) ssh.close()
2. 批量执行sudo命令(仅输入一次密码)
使用交互式Shell通道实现会话状态保持,示例如下:
import paramiko import time ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname='主机IP', port=22, username='普通用户名', password='普通用户密码') sudo_password = "你的sudo密码" # 开启交互式shell shell = ssh.invoke_shell() # 等待shell加载完成 time.sleep(0.5) # 切换到root shell,后续所有命令都以root执行 shell.send("sudo -s\n") time.sleep(0.5) # 输入sudo密码 shell.send(f"{sudo_password}\n") time.sleep(0.5) # 清空缓冲区的提示符和密码回显内容 recv = shell.recv(65535).decode() # 批量执行命令列表,可按需添加 commands = [ "ls -l /root", "cat /etc/shadow | head -5", "df -h" ] for cmd in commands: shell.send(f"{cmd}\n") # 等待命令执行完成,可根据命令实际执行时长调整等待时间 time.sleep(1) # 读取输出 output = shell.recv(65535).decode() print(f"命令【{cmd}】的输出:") print(output) shell.close() ssh.close()
注:如果不想直接切换到root shell,也可以去掉
sudo -s的步骤,执行每条命令时加sudo前缀,同一会话内默认5分钟内不需要重复输入密码。
内容的提问来源于stack exchange,提问作者brucelona
相关产品推荐
相关产品推荐

