You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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和密码输入的问题。

  1. 远程登录主机,执行sudo visudo(一定要用visudo编辑,避免语法错误导致sudo失效)
  2. 在文件末尾添加一行(替换成你的用户名和命令路径):
    username ALL=(ALL) NOPASSWD: /bin/hostname
    
  3. 保存退出后,再用Paramiko执行sudo hostname就不会报错了,代码可以简化成:
    # ... 前面的连接代码不变
    stdin, stdout, stderr = ssh.exec_command('sudo hostname')
    # ... 读取结果代码
    

需要注意的是,第二种方法要谨慎使用,避免给过大的权限,只给需要的命令开NOPASSWD权限就好。

内容的提问来源于stack exchange,提问作者user1248238

火山引擎 最新活动