首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Paramiko -远程命令执行

Paramiko -远程命令执行
EN

Stack Overflow用户
提问于 2014-03-18 03:53:22
回答 1查看 1.1K关注 0票数 1

在执行某些命令时,Paramiko返回得很好。对于在远程shell上运行的特定set命令,执行挂起,并在终止进程时捕获以下错误。

代码语言:javascript
复制
Exception executing the tests
Traceback (most recent call last):
  File "cli_automation.py", line 333, in executeTests
    output = stdout.read()
  File "/usr/local/lib/python2.7/site-packages/paramiko-1.12.2-py2.7.egg/paramiko/file.py", line 134, in read
    new_data = self._read(self._DEFAULT_BUFSIZE)
  File "/usr/local/lib/python2.7/site-packages/paramiko-1.12.2-py2.7.egg/paramiko/channel.py", line 1260, in _read
    return self.channel.recv(size)
  File "/usr/local/lib/python2.7/site-packages/paramiko-1.12.2-py2.7.egg/paramiko/channel.py", line 617, in recv
    out = self.in_buffer.read(nbytes, self.timeout)
  File "/usr/local/lib/python2.7/site-packages/paramiko-1.12.2-py2.7.egg/paramiko/buffered_pipe.py", line 137, in read
    self._cv.wait(timeout)
  File "/usr/local/lib/python2.7/threading.py", line 244, in wait
    waiter.acquire()
KeyboardInterrupt
EN

回答 1

Stack Overflow用户

发布于 2015-10-26 04:14:05

请参阅另一个问题的my answer,该问题包含exec_command的自定义实现,该实现避免了常见的挂起和空响应场景:

代码语言:javascript
复制
def myexec(cmd, timeout, want_exitcode=False):
  # one channel per command
  stdin, stdout, stderr = ssh.exec_command(cmd) 
  # get the shared channel for stdout/stderr/stdin
  channel = stdout.channel

  # we do not need stdin.
  stdin.close()                 
  # indicate that we're not going to write to that channel anymore
  channel.shutdown_write()      

  # read stdout/stderr in order to prevent read block hangs
  stdout_chunks = []
  stdout_chunks.append(stdout.channel.recv(len(c.in_buffer)))
  # chunked read to prevent stalls
  while not channel.closed or channel.recv_ready() or channel.recv_stderr_ready(): 
      # stop if channel was closed prematurely
      got_chunk = False
      readq, _, _ = select.select([stdout.channel], [], [], timeout)
      for c in readq:
          if c.recv_ready(): 
              stdout_chunks.append(stdout.channel.recv(len(c.in_buffer)))
              got_chunk = True
          if c.recv_stderr_ready(): 
              # make sure to read stderr to prevent stall    
              stderr.channel.recv_stderr(len(c.in_stderr_buffer))  
              got_chunk = True  
      '''
      1) make sure that there are at least 2 cycles with no data in the input buffers in order to not exit too early (i.e. cat on a >200k file).
      2) if no data arrived in the last loop, check if we already received the exit code
      3) check if input buffers are empty
      4) exit the loop
      '''
      if not got_chunk \
          and stdout.channel.exit_status_ready() \
          and not stderr.channel.recv_stderr_ready() \
          and not stdout.channel.recv_ready(): 
          # indicate that we're not going to read from this channel anymore
          stdout.channel.shutdown_read()  
          # close the channel
          stdout.channel.close()
          break    # exit as remote side is finished and our bufferes are empty

  # close all the pseudofiles
  stdout.close()
  stderr.close()

  if want_exitcode:
      # exit code is always ready at this point
      return (''.join(stdout_chunks), stdout.channel.recv_exit_status())
  return ''.join(stdout_chunks)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22464020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档