使用Python的Paramiko模块切换root用户时提示‘must be run from a terminal’
解决su命令"must be run from a terminal"错误的方法
你碰到这个问题,核心原因是su是一个依赖交互式终端(tty)的命令——它需要终端环境来接收密码输入,但默认调用ssh.exec_command('su')时,并没有为这个命令分配伪终端,所以才会抛出这个错误。下面给你两个可行的解决办法:
方法一:给exec_command开启伪终端
在调用exec_command时加上get_pty=True参数,就能为命令分配一个伪终端,满足su的运行要求。示例代码如下:
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('你的主机地址', username='普通用户名', password='普通用户密码') # 开启伪终端执行su命令 stdin, stdout, stderr = ssh.exec_command('su', get_pty=True) # 输入root密码,记得加上换行符模拟回车 stdin.write('root密码\n') stdin.flush() # 接下来就可以执行需要root权限的命令了,比如验证身份 stdin.write('whoami\n') stdin.flush() # 读取并打印输出结果 print(stdout.read().decode()) ssh.close()
方法二:用invoke_shell创建交互式会话
如果需要连续执行多个交互式命令,使用invoke_shell会更灵活,它会创建一个完整的交互式shell环境:
import paramiko import time ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('你的主机地址', username='普通用户名', password='普通用户密码') # 创建交互式shell会话 shell = ssh.invoke_shell() # 给shell一点初始化时间 time.sleep(1) # 发送su命令 shell.send('su\n') time.sleep(1) # 发送root密码 shell.send('root密码\n') time.sleep(1) # 发送需要执行的root权限命令,比如查看root目录 shell.send('ls /root\n') time.sleep(1) # 获取并打印输出内容 output = shell.recv(65535).decode() print(output) ssh.close()
额外提醒:你也提到明文输入密码的做法不规范,这一点非常正确。在生产环境中,更安全的替代方案是给普通用户配置sudo免密权限,或者使用密钥认证方式,彻底避免明文传递密码的安全风险。
内容的提问来源于stack exchange,提问作者user2500239
相关产品推荐
相关产品推荐

