Python新手求助:Paramiko执行sudo命令报无终端及askpass错误
解决Paramiko执行sudo命令报错:sudo: no tty present and no askpass program specified
嘿,刚接触Python和Paramiko遇到这个问题很正常,我来帮你捋清楚怎么搞定它!
首先,这个报错的核心原因是:sudo默认需要一个交互式终端(tty)来让你输入密码,但Paramiko的exec_command默认不会为远程命令分配终端,所以即使你加了-S(让sudo从标准输入读密码),也因为没有tty环境导致没法正常工作。
下面给你两种可行的解决方案,按需选择:
方案一:分配终端并通过stdin传递密码
这是最直接的方法,在调用exec_command时加上get_pty=True参数分配终端,同时配合-S让sudo从stdin读取密码,代码示例如下:
import paramiko # 替换成你的实际信息 host = "远程主机IP" username = "你的用户名" password = "你的密码" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.load_system_host_keys() ssh.connect(host, 22, username, password, timeout=5) # 关键:get_pty=True 分配终端,-S 让sudo从stdin读密码 stdin, stdout, stderr = ssh.exec_command('sudo -S hostname', get_pty=True) # 写入密码后一定要加换行符,否则sudo会一直等待输入 stdin.write(f"{password}\n") stdin.flush() # 强制把缓冲区的内容发送出去 # 读取命令执行结果 cmd_output = stdout.read().decode('utf-8') cmd_error = stderr.read().decode('utf-8') print("命令输出:\n", cmd_output) print("错误信息:\n", cmd_error) ssh.close()
方案二:修改远程主机sudoers配置(无需输入密码)
如果你有权限修改远程主机的sudo配置,可以让特定用户执行特定命令时不需要输入密码,这样就绕开了tty和密码输入的问题。
- 远程登录主机,执行
sudo visudo(一定要用visudo编辑,避免语法错误导致sudo失效) - 在文件末尾添加一行(替换成你的用户名和命令路径):
username ALL=(ALL) NOPASSWD: /bin/hostname - 保存退出后,再用Paramiko执行
sudo hostname就不会报错了,代码可以简化成:# ... 前面的连接代码不变 stdin, stdout, stderr = ssh.exec_command('sudo hostname') # ... 读取结果代码
需要注意的是,第二种方法要谨慎使用,避免给过大的权限,只给需要的命令开NOPASSWD权限就好。
内容的提问来源于stack exchange,提问作者user1248238




