python - 从Python Paramiko获取非控制台(ish)结果

标签 python paramiko fabric

我不是初学者,但我主要使用C,而不是Python。我正在尝试使用Paramiko编写Python脚本来访问SSH服务器。

它的连接很好,但我还不太确定如何等待返回数据。

登录SSH服务器后,它会在控制台上运行一个应用程序,然后需要登录。

如何等待应用程序完成其输出,然后发送所需的登录名和密码?

我知道Fabric之类的其他库,但是我也找不到适合他们的方法。

import sys
from paramiko import client

class ssh:
    client = None

    def __init__(self, address, username, password):

        print("Connecting to server.")

        self.client = client.SSHClient()

        self.client.set_missing_host_key_policy(client.AutoAddPolicy())

        self.client.connect(address, username=username, password=password, look_for_keys=False)

    def sendCommand(self, command):

        # Check if connection is made previously.
        if(self.client):

            stdin, stdout, stderr = self.client.exec_command(command)

            while not stdout.channel.exit_status_ready():

                # Print data when available.
                if stdout.channel.recv_ready():

                    # Retrieve the first 1024 bytes.
                    alldata = stdout.channel.recv(1024)
                    prevdata = b"1"

                    while prevdata:
                        # Retrieve the next 1024 bytes.
                        prevdata = stdout.channel.recv(1024)
                        alldata += prevdata

                    print(str(alldata, "utf8"))
        else:
            print("Connection not opened.")

def main ():


    connection = ssh("SOME_IP", "USERNAME", "PASSWORD")

    connection.sendCommand("ls") # This works fine 
                                 # (on a system with no application running after login) 
                                 # so I know all is good

    # The problem is that after login an application is run automatically
    # that displays an input screen and waits for a different login and password.

    # I cant find a way to detect this screen has finished loading before I send login details.

    # I cant use "sendCommand" as the application runs straight after login, 
    # there is no command to send.

    # The actual end goal is to scrape the output from the application
    # after logging in and selecting a few options.

if __name__ == '__main__':
    sys.exit(main())

最佳答案

试试看:

#!/usr/bin/env python

import sys
import time
import paramiko

SSH_SERVER_IP ="IP_ADDRESS"

def main():

    client = paramiko.SSHClient()

    try:

        print("Establishing a connection to %s.\n" % SSH_SERVER_IP)

        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        client.connect(SSH_SERVER_IP, username="USERNAME", password="PASSWORD", look_for_keys=False)

        print("SSH connection established to %s.\n" % SSH_SERVER_IP)

    except paramiko.ssh_exception.BadHostKeyException:
        print("ERROR: The server's host key could not be verified. Exiting program.")
    except paramiko.ssh_exception.AuthenticationException: 
        print("ERROR: Authentication has failed. Exiting program.")
    except paramiko.ssh_exception.SSHException: 
        print("ERROR: There has been a problem connecting or establishing an SSH session. Exiting program.")
    except paramiko.ssh_exception.socket.error:
        print("ERROR: A socket error has occurred. Exiting program.")

    if(client):

        # A channel is a secure tunnel across an SSH Transport. A Channel is meant to behave like a socket, 
        # and has an API that should be indistinguishable from the Python socket API.

        # Start a shell session on the SSH server.
        # A channel is opened and connected to a pseudo-terminal and the channel ready to execute commands.
        # I used vt100 term with 250X100 terminal size.

        channel = client.invoke_shell(term="vt100", width=250, height=100)
        channel.settimeout(0.0)

        try:

            # wait until channel is ready.
            while not channel.recv_ready() :
                print("Waiting for recv_ready()\n\n")
                time.sleep(1)
                # Maybe add something here to stop infinite loop.

            receive_buffer = channel.recv(1024)

            print(receive_buffer)

            # Send a command to the channel.
            channel.send("SOME_COMMAND_OR_DATA")

        except Exception as ex:
            print("Error: ", ex)

        channel.close()

    else:
        print("No SSHClient connection available.")

    if(client):
        client.close()

if __name__ == '__main__':
    sys.exit(main())

关于python - 从Python Paramiko获取非控制台(ish)结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55153094/

相关文章:

Python Fabric 不会传入变量

python - 插入 python 数组以最小化元素之间的最大差异

python - 在 python 中使用 notify-send 显示多行通知

python - 如何使用 python 有条件替换文本文件中的子字符串

python - paramiko 无法连接到 ssh 服务器

python - 使用命名空间构建结构项目

python - 如何使用 SQLAlchemy Core 通过子查询插入多个值?

Python - 如何验证与 Fabric 模块的 SSH 连接?

python - Paramiko SSH exec_command(shell脚本)在完成前返回

Python Fabric 从单独的文件加载配置