使用Paramiko PTY执行命令报错:write()参数需为str而非bytes
解决Paramiko实时读取带PTY的SSH命令输出问题
错误原因
stdout.channel.recv(1024)返回的是字节流(bytes类型),而sys.stdout.write()仅接受字符串(str类型),直接写入会触发类型错误。
修正方案
方案1:解码字节流后输出(适配原代码逻辑)
将读取到的字节流解码为字符串,再写入标准输出,同时保留实时刷新的逻辑:
import paramiko import sys ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy) ssh.connect('my.host.com', 22, 'root', key_filename="/home/me/.ssh/id_ed25519") stdin, stdout, stderr = ssh.exec_command("ls", get_pty=True) while True: # 按UTF-8解码字节流,可根据远程机器编码调整(如gbk) output_bytes = stdout.channel.recv(1024) if not output_bytes: break output_str = output_bytes.decode('utf-8') sys.stdout.write(output_str) sys.stdout.flush() ssh.close()
方案2:逐行读取并实时输出(更简洁)
利用stdout.readline()实现逐行读取,同时通过iter()构造循环,确保实时输出:
import paramiko import sys ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy) ssh.connect('my.host.com', 22, 'root', key_filename="/home/me/.ssh/id_ed25519") stdin, stdout, stderr = ssh.exec_command("ls", get_pty=True) # 迭代读取每一行,直到返回空字符串 for line in iter(stdout.readline, ''): sys.stdout.write(line) sys.stdout.flush() ssh.close()
注意事项
- 由于设置了
get_pty=True,远程命令的输出可能包含终端控制字符(如颜色代码、光标移动指令),如果需要纯文本输出,可额外处理过滤这些字符。 - 解码时的编码格式需与远程机器的系统编码一致,默认用
utf-8,若远程是中文环境可尝试gbk。
内容的提问来源于stack exchange,提问作者gameveloster
相关产品推荐
相关产品推荐

