Paramiko SSH执行命令卡在session.recv_exit_status()

时间:2015-02-11 05:33:29

标签: python python-2.7 python-3.x paramiko

下面是我的Python代码,它运行良好,直到我尝试使用别名来源一些环境变量。从那以后它开始挂在session.recv_exit_status(),现在甚至拒绝执行ls命令。

#!/usr/bin/env/python

import paramiko
trans = paramiko.Transport(('fcd01.force.com',22))
trans.connect(username = 'user',password = 'pwd')
session = trans.open_channel("session")

session.exec_command('ls')
session.recv_exit_status()  # ** hangs **

while True:
    if session.recv_ready():
        break
    time.sleep(2)
session.send('exit\n')

stdout_data = []
try:
    part = session.recv(4096)
while part:
    stdout_data.append(part)
    part = session.recv(4096)
except:
    raise

print 'exit status: ', session.recv_exit_status()
print ''.join(stdout_data)

如何获得成功的任何线索?

2 个答案:

答案 0 :(得分:0)

由于以下SO帖子,我通过在函数中放置连接和执行命令来解决问题:Why does Paramiko hang if you use it while loading a module?

就代码而言,您需要使用try-catches显式关闭连接,例如:

try:
    session.exec_command("ls")
except **some paramiko exception**:
    session.close()

但是,使用SSHClient可以简化您的代码。

import paramiko

ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect(username="user", password="pwd", hostname="fcd01.force.com", port=22)
try:
    stdin, stdout, stderr = ssh.exec_command("ls")
except SSHException:
    ssh.close()
else:
    **do something with stdout then close the connection**

如果你正在寻找一个交互式终端,你需要特定的提示来发出更多输入信号,例如PowerBroker访问(sudo访问),那么使用while循环并获取字节数会更好。 如果您只发送一个命令并获得响应,然后另一个命令并获得响应,每个命令都不等待服务器上另一个命令的提示,那么您绝对不需要读取数据转回来。

另外,请记住,SSHClient的exec_command()实际上会在完成后关闭底层传输,并且每次都会创建一个新传输。您始终需要显式关闭ssh连接。

答案 1 :(得分:0)

是的,在尝试运行交互式会话时,我搞砸了ssh连接。现在它永久锁定。这是我运行命令行时的输出。

*** Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32. ***
*** Remote Python engine  is active ***
>>> import paramiko
>>> ssh = paramiko.SSHClient()
>>> print ssh
<paramiko.client.SSHClient object at 0x02EEDB10>
>>> print ssh.get_transport()
None
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.connect('fcd01.force.com',username = 'user',password = 'pwd')
>>> print ssh
<paramiko.client.SSHClient object at 0x02EEDB10>
>>> print ssh.get_transport()
<paramiko.Transport at 0x2ef8f90L (cipher aes128-ctr, 128 bits) (active; 0  open channel(s))>
>>> print ssh.get_transport().is_active()
True
>>> ssh.exec_command('ls')
(<paramiko.ChannelFile from <paramiko.Channel 0 (open) window=2097152 ->    <paramiko.Transport at 0x2ef8f90L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>>,

&gt;&gt;,   &GT;&GT)

  
    
      

打印ssh           

    
  

如果我执行stdin,stdout stderr = ssh.exec_command(&#39; ls&#39;)然后打印stdout.readlines(),PyScripter挂起(或者即使我从命令提示符运行脚本,它也会挂起) 。我似乎首先需要断开或关闭与服务器的现有连接,我不知道该怎么做。

ssh.exec_command(&#39; ls&#39;)的输出在Pyscripter中打印了三次(3次),它只粘贴了一次。