我不是初学程序员,但我主要使用的是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())