使用paramiko进程远程操作时,如果缓冲区满了,exec_command在写入该缓冲区时会产生阻塞并一直保持阻塞状态,直到缓冲区被清空为止。
使用multiprocessing无疑会加重这种情况,其中一种解决办法是设置exec_command的get_pty参数为True:
def ssh_command(cmd, ip, port, user, passwd, out):
ssh = paramiko.SSHClient()
# ssh._transport = transport
"""
The authenticity of host '172.25.254.221 (172.25.254.221)' can't be established.
ECDSA key fingerprint is 4c:98:51:43:65:46:66:fd:af:5b:ea:cc:d9:97:c0:74.
Are you sure you want to continue connecting (yes/no)?
"""
# 自动选择yes
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
print('ssh.connect: {} port: {}, command: {}'.format(ip, port, cmd))
ssh.connect(ip, port, user, passwd, allow_agent=False)
except Exception as e:
ssh.close()
out.append(e)
return ERROR_SSH_CONNECT_FAILED
stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
# 实时输出
while not stdout.channel.exit_status_ready():
result = stdout.readline()
out.append(result)
if stdout.channel.exit_status_ready():
result = stdout.readline()
out.append(result)
ssh.close()
return 0
SSHClient的相关介绍:
https://www.cnblogs.com/caesar-id/p/12873557.html
class paramiko.client.SSHClient
SSHClient是与SSH服务器回话的高级封装,其内部实现了身份验证,执行命令等大多数基础功能。
exec_command(
command,
bufsize=-1,
timeout=None,
get_pty=False,
environment=None,
)
command(str):要执行的命令,多条命令用分号隔开。
bufsize(int):0 表示不缓冲,如果为 1 表示进行行缓冲,大于 1 为缓冲区大小。
timeout(float):命令执行的超时时间,单位秒。
get_pty(bool):如果为True相当于Channel.get_pty,向服务器请求一个伪终端。
environment(dict):在执行命令时附加环境变量。
返回值:返回一个元组 (stdin, stdout, stderr)
class paramiko.channel.Channel(chanid)
channel是一个SSH传输的安全隧道。一个通道类似于一个socket,由于SSH2有一种窗口式的流控制,如果停止从channel中读取数据,并且其缓冲区已满,服务器将无法向channel发送更多的数据,直到从channel中读取其中一些数据。(注意:这不会影响同一传输上的其他channel,单个传输上的所有channel都是独立的流控制。)同样,如果服务器不读取channel发送的数据,则除非设置超时,否则发送调用会一直处于阻塞。
get_pty(term="vt100",width=80,height=24,width_pixels=0,height_pixels=0)
功能:向服务器请求获取一个伪终端,通常在创建channel后,立即调用get_pty()请求一个伪终端,在使用invoke_shell想要创建一个交互式shell环境时需要提前调用get_pty(),如果调用的是exec_command执行命令,不需要使用get_pty()。
参考资料:
https://www.cnblogs.com/xiaofeng91/p/15070097.html
paramiko的get_pty=True参数_莺声门径的博客-CSDN博客_get_pty=true
关于python:读取大输出时,Paramiko通道卡住 | 码农家园