4

接続を作成するクラスがあります。チャネルが閉じられる前に、接続して 1 つのコマンドを実行できます。別のシステムでは、複数のコマンドを実行できますが、チャネルが閉じません。明らかに、接続しようとしているシステムの構成の問題です。

class connect:

    newconnection = ''

    def __init__(self,username,password): 
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect('somehost', username=username,password=password,port=2222,timeout=5)
        except:
            print "Count not connect"
            sys.exit()
        self.newconnection = ssh

    def con(self):
        return self.newconnection

次に、「ls」コマンドを使用して出力を印刷します

sshconnection = connect('someuser','somepassword').con()


stdin, stdout, stderr = sshconnection.exec_command("ls -lsa")

print stdout.readlines() 
print stdout 

stdin, stdout, stderr = sshconnection.exec_command("ls -lsa")

print stdout.readlines() 
print stdout 

sshconnection.close()
sys.exit()

最初の exec_command が実行された後、予想されるディレクトリ リストの出力が出力されます。最初の exec_command の後に stdout を出力すると、チャネルが閉じているように見えます

<paramiko.ChannelFile from <paramiko.Channel 1 (closed) -> <paramiko.Transport at 0x2400f10L (cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>>> 

別のシステムで言ったように、コマンドを実行し続けることができ、接続が閉じません。これを開いたままにしておく方法はありますか?または、閉じる理由を確認できるより良い方法はありますか?

edit : SSHClient.exec_command ごとに 1 つのコマンドしか実行できないように見えるので、get_transport().open_session() を実行してからコマンドを実行することにしました。最初のものは常に機能します。2 つ目は常に失敗し、スクリプトがハングするだけです

4

3 に答える 3

5

が実行された直後paramikoexec_commandチャネルが閉じられssh、認証プロンプトが返されます。

paramiko、 tryfabricまたは別のツールだけでは不可能なようです。

**fabricもうまくいきませんでした。

于 2013-11-08T19:32:15.240 に答える
2

Paramiko でこれを行う方法については、次のリファレンスを参照してください。

Paramiko の 1 つのセッションで複数のコマンドを実行するにはどうすればよいですか? (パイソン)

于 2014-02-04T23:42:37.337 に答える
1

netmiko (Windows でテスト済み) で可能です。この例は cisco デバイスに接続するために書かれていますが、原則は他のデバイスにも適用できます。

import netmiko
from netmiko import ConnectHandler
import json

def connect_enable_silent(ip_address,ios_command):
    with open ("credentials.txt") as line:
        line_1 = json.load(line)
        for k,v in line_1.items():
            router=(k,v)
            try:
                ssh = ConnectHandler(**router[1],device_type="cisco_ios",ip=ip_address)
                ssh.enable()
            except netmiko.ssh_exception.NetMikoAuthenticationException:
                #incorrect credentials
                continue
            except netmiko.ssh_exception.NetMikoTimeoutException:
                #oddly enough if it can log in but not able to authenticate to enable mode the ssh.enable() command does not give an authentication error
                #but a time-out error instead
                try:
                    ssh = ConnectHandler(username = router[1]['username'],password = router[1]['password'],device_type="cisco_ios", ip=ip_address)
                except netmiko.ssh_exception.NetMikoTimeoutException:
                    # connection timed out (ssh not enabled on device, try telnet)
                    continue
                except Exception:
                    continue
                else:
                    output = ssh.send_command(ios_command)
                    ssh.disconnect()
                    if "at '^' marker." in output:
                        #trying to run a command that requires enble mode but not authenticated to enable mode
                        continue
                    return output
            except Exception:
                continue
            else:
                output = ssh.send_command(ios_command)
                ssh.disconnect()
                return output

output = connect_enable_silent(ip_address,ios_command)
for line in output.split('\n'):
    print(line)

Credentials テキストは、この関数を呼び出して複数のデバイスにアクセスし、すべてのデバイスが同じ資格情報を使用するわけではない場合に備えて、さまざまな資格情報を格納するためのものです。形式は次のとおりです。

{"credentials_1":{"username":"username_1","password":"password_1","secret":"secret_1"},
"credentials_2":{"username":"username_2","password":"password_2","secret":"secret_2"},
"credentials_3": {"username": "username_3", "password": "password_3"}
}

例外はさまざまなことを行うように変更できます。私の場合、エラーを返さずに次のセットを試行し続けるために必要だったので、ほとんどの例外が沈黙しています。

于 2016-05-13T19:09:35.630 に答える