[PYTHON] 큰 출력을 읽을 때 Paramiko 채널이 멈 춥니 다.
PYTHON큰 출력을 읽을 때 Paramiko 채널이 멈 춥니 다.
필자는 원격 Linux 컴퓨터에서 명령을 실행하고 Paramiko를 사용하여 출력을 읽는 코드를 가지고 있습니다. 코드 def는 다음과 같습니다.
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(IPAddress, username=user['username'], password=user['password'])
chan = self.ssh.get_transport().open_session()
chan.settimeout(10800)
try:
# Execute thecommand
chan.exec_command(cmd)
contents = StringIO.StringIO()
data = chan.recv(1024)
# Capturing data from chan buffer.
while data:
contents.write(data)
data = chan.recv(1024)
except socket.timeout:
raise socket.timeout
output = contents.getvalue()
return output,chan.recv_stderr(600),chan.recv_exit_status()
위의 코드는 작은 출력에서는 작동하지만 큰 출력에서는 문제가됩니다.
여기에 버퍼 관련 문제가 있습니까?
해결법
-
==============================
1.stdout 채널과 관련된 문제는 보이지 않지만 stderr을 처리하는 방법에 대해서는 확실하지 않습니다. 문제를 일으키는 표준 오류를 포착 한 것이 아니라 확인할 수 있습니까? 코드를 시험해보고 알려 드리겠습니다.
stdout 채널과 관련된 문제는 보이지 않지만 stderr을 처리하는 방법에 대해서는 확실하지 않습니다. 문제를 일으키는 표준 오류를 포착 한 것이 아니라 확인할 수 있습니까? 코드를 시험해보고 알려 드리겠습니다.
최신 정보: STDERR에서 실행하는 명령이 많은 메시지를 제공하면 코드가 멈 춥니 다. 왜 그런지는 모르지만 recv_stderr (600)이 이유 일 수 있습니다. 따라서 표준 출력을 캡처하는 것과 같은 방식으로 오류 스트림을 캡처하십시오. 어떤 것,
contents_err = StringIO.StringIO() data_err = chan.recv_stderr(1024) while data_err: contents_err.write(data_err) data_err = chan.recv_stderr(1024)
recv_stderr (600) 이상을 recv_stderr (1024) 이상으로 변경해보십시오.
-
==============================
2.나는 브루스 웨인 (:)으로부터 입력으로 작업 한 최종 코드를 게시하고 있습니다.
나는 브루스 웨인 (:)으로부터 입력으로 작업 한 최종 코드를 게시하고 있습니다.
ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(IPAddress, username=user['username'], password=user['password']) chan = self.ssh.get_transport().open_session() chan.settimeout(10800) try: # Execute the given command chan.exec_command(cmd) # To capture Data. Need to read the entire buffer to capture output contents = StringIO.StringIO() error = StringIO.StringIO() while not chan.exit_status_ready(): if chan.recv_ready(): data = chan.recv(1024) #print "Indside stdout" while data: contents.write(data) data = chan.recv(1024) if chan.recv_stderr_ready(): error_buff = chan.recv_stderr(1024) while error_buff: error.write(error_buff) error_buff = chan.recv_stderr(1024) exit_status = chan.recv_exit_status() except socket.timeout: raise socket.timeout output = contents.getvalue() error_value = error.getvalue() return output, error_value, exit_status
-
==============================
3.사실 위의 모든 대답이 실제 문제를 해결할 수 없다고 생각합니다.
사실 위의 모든 대답이 실제 문제를 해결할 수 없다고 생각합니다.
원격 프로그램이 stderr 출력을 대량으로 생성한다면
stdout.readlines() stderr.readlines()
영원히 걸릴 것입니다. 이기는 하지만
stderr.readlines() stdout.readlines()
이 경우는 해결되지만 원격 프로그램이 대량의 stdout 출력을 먼저 생성하는 경우 실패합니다.
아직 해결책이 없습니다 ...
-
==============================
4.열린 ssh 세션의 상위 레벨 표현을 사용하면 더 쉽습니다. 이미 ssh-client를 사용하여 채널을 열었으므로 그곳에서 명령을 실행하고 추가 작업을 피할 수 있습니다.
열린 ssh 세션의 상위 레벨 표현을 사용하면 더 쉽습니다. 이미 ssh-client를 사용하여 채널을 열었으므로 그곳에서 명령을 실행하고 추가 작업을 피할 수 있습니다.
ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(IPAddress, username=user['username'], password=user['password']) stdin, stdout, stderr = ssh.exec_command(cmd) for line in stdout.readlines(): print line for line in stderr.readlines(): print line
이후에 추가 데이터를 받으면 다시 돌아와서이 파일에서 읽어야합니다.
-
==============================
5.paramiko 명령을 subprocess.call처럼 동작 시키려면 다음 코드를 사용할 수 있습니다 (python-3.5 및 paramiko-2.1.1에서 테스트 됨).
paramiko 명령을 subprocess.call처럼 동작 시키려면 다음 코드를 사용할 수 있습니다 (python-3.5 및 paramiko-2.1.1에서 테스트 됨).
#!/usr/bin/env /usr/bin/python3 import os import sys from paramiko import SSHClient, AutoAddPolicy from socket import getfqdn class SecureSHell(object): reuser = os.environ['USER'] remote = '' def __init__(self, *args, **kwargs): for arg in args: if hasattr(self, arg): setattr(self, arg, True) for (key, val) in kwargs.items(): if hasattr(self, key): setattr(self, key, val) @staticmethod def _ssh_(remote, reuser, port=22): if '@' in remote: _reuser, remote = remote.split('@') _fqdn = getfqdn(remote) remote = _fqdn if _fqdn else remote ssh = SSHClient() ssh.set_missing_host_key_policy(AutoAddPolicy()) ssh.connect(remote, int(port), username=reuser) return ssh def call(self, cmd, remote=None, reuser=None): remote = remote if remote else self.remote reuser = reuser if reuser else self.reuser ssh = self._ssh_(remote, reuser) chn = ssh.get_transport().open_session() chn.settimeout(10800) chn.exec_command(cmd) while not chn.exit_status_ready(): if chn.recv_ready(): och = chn.recv(1024) while och: sys.stdout.write(och.decode()) och = chn.recv(1024) if chn.recv_stderr_ready(): ech = chn.recv_stderr(1024) while ech: sys.stderr.write(och.decode()) ech = chn.recv_stderr(1024) return int(chn.recv_exit_status()) ssh = SecureSHell(remote='example.com', user='d0n') ssh.call('find')
from https://stackoverflow.com/questions/14643861/paramiko-channel-stucks-when-reading-large-ouput by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 플라스크에서 체크 박스를 선택하는 방법 (0) | 2018.11.28 |
---|---|
[PYTHON] python NameError : 전역 이름 '__file__'이 (가) 정의되지 않았습니다. (0) | 2018.11.28 |
[PYTHON] matplotlib를 사용하는 코드에 대해 단위 테스트를 작성하려면 어떻게해야합니까? (0) | 2018.11.28 |
[PYTHON] 왜 PyQt connect () 구문이 그렇게 장황합니까? (0) | 2018.11.28 |
[PYTHON] sklearn : 다항식의 계수를 구하는 방법 (0) | 2018.11.28 |