2012-11-15 5 views
5

저는 원격 컴퓨터에 SSH를 사용하기 위해 python의 paramiko 모듈을 사용하고 많은 파일 (60K 이상의 파일 및 60GB 이상의 데이터)이있는 폴더를 Tar/ZIP합니다. 생성 된 우편 번호는 약 10 기가 자체입니다. 이제 문제없이 컴퓨터에서 zip/tar 명령을 직접 실행할 수 있습니다. 그러나 SSHClient의 exec_command를 통해 동일한 명령을 실행하려고하면이 명령이 약간 실행되지만 결국 원격 시스템의 압축 프로세스가 잠자기 상태가됩니다. 그리고 recv_exit_status는 무기한으로 정지합니다. 여기에 내가 사용하고 코드는 다음과 같습니다paramiko exec_command 명령을 실행하면 작업이 완료되기 전에 잠자기 상태가됩니다.

stdin, stdout, stderr = ssh.exec_command('cd myDirectory; tar -zcvf output.tgz *') 
status = stdout.channel.recv_exit_status() 

가 나는 또한 우편 번호를 사용했습니다. 내가 원격 시스템에서 직접 명령을 실행하면 두 경우 모두

stdin, stdout, stderr = ssh.exec_command('cd myDirectory; find -name "*.gz" | zip output.zip [email protected]') 
status = stdout.channel.recv_exit_status() 

, 그것은/용기 중량을 측정을 압축하는 완료. 결과 파일은 9 기가와 같습니다. 그러나 paramiko에서 그것을 시도 할 때, 시작, 절반 이상 (6 기가) 이상으로 진행하고 그 과정은 잠들게됩니다!

top을 사용하여 원격 시스템의 프로세스를 모니터링 했으므로 zip/tar가 실행되기 시작하지만 결국 완료되기 전에 잠자기 상태가됩니다. 파이썬 스크립트는 무한정 정지됩니다.

왜 이런 생각입니까?

+0

내 업데이트 된 대답을 참조하십시오 36736691/4988742 그게 해결되는지 알려주세요. 이미 해결했다면 솔루션을 친절하게 공유하십시오. –

답변

1

시간 제한과 관련 될 수 있습니다. 통화에 timeout 매개 변수 (초 단위)를 추가하십시오 (exec_command(timeout=20*60)). 이것은 20 분 예입니다. 대한 추가 정보를 원하시면 그 방법의 문서화 문자열을 참조하십시오 https://github.com/paramiko/paramiko/issues/109

나는이 문제가 발생 https://github.com/paramiko/paramiko/issues/109#issuecomment-111621658

내 제안을 시도해보십시오

def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False): 
    """ 
    Execute a command on the SSH server. A new `.Channel` is opened and 
    the requested command is executed. The command's input and output 
    streams are returned as Python ``file``-like objects representing 
    stdin, stdout, and stderr. 

    :param str command: the command to execute 
    :param int bufsize: 
     interpreted the same way as by the built-in ``file()`` function in 
     Python 
    :param int timeout: 
     set command's channel timeout. See `Channel.settimeout`.settimeout 
    :return: 
     the stdin, stdout, and stderr of the executing command, as a 
     3-tuple 

    :raises SSHException: if the server fails to execute the command 
    """ 

는 또한 또한 기여할 수있는 내가 경험 또 다른 문제가 있습니다 그것은 stdout.channel.eof_received == 0으로 인한 것입니다.

import paramiko 
client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect("1.1.1.1", username="root", password="pass") 
stdin, stdout, stderr = client.exec_command("service XXX start") 

stdout, stdout 및 stderr은 보통 내가 진정한받을 수있는 단지 stdout.read(),하지만 난 이것을 사용 안전을 위해

>>> print stdin.channel.eof_received 
0 

>>> print stdin 
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>> 
>>> print stdout 
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>> 
>>> print stderr 
<paramiko.ChannelFile from <paramiko.Channel 3 (open) window=2097152 in-buffer=50 -> <paramiko.Transport at 0x17eff90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>> 
그래서 EOF가 수신되지

...

... 개방 머물고있는 (작품!) 해결 방법 : stdout.channel.close를 (강제로, 타임 아웃 기다립니다) 다음 stdout.read은() : http://stackoverflow.com/a/ :

>>> timeout = 30 
>>> import time 
>>> endtime = time.time() + timeout 
>>> while not stdout.channel.eof_received: 
...  sleep(1) 
...  if time.time() > endtime: 
...   stdout.channel.close() 
...   break 
>>> stdout.read() 
'Starting XXX: \n[ OK ]\rProgram started . . .\n' 
>>>