Python Parimiko无法将进度和数据加载到文本框中

时间:2018-12-07 11:48:36

标签: python tkinter paramiko

我目前正在构建脚本以自动执行备份过程。该脚本可以很好地将输出内容从外壳程序转储到文本框中,直到第6步实际发生后退过程为止。在外壳程序中,它使用“ .....”作为进度条,但是在脚本完成时,它不会在文本框中显示其输出,而在打印时仅在控制台中显示。我希望此输出显示在文本框中。无论如何,我还能继续循环检查这些关键字以检测命令是否完成,而不是通过睡眠来猜测吗?谢谢

import datetime, time
from time import sleep
from Tkinter import *
import paramiko
def cms():
    canvas = Canvas(page3, relief = FLAT, background = "#D2D2D2", width = 694, height = 120)
    canvas.pack()  
    txtOutput = Text(canvas, wrap = NONE, height =14, width = 86, borderwidth=2)
    txtOutput.pack()
    try:
       ssh = paramiko.SSHClient()
       ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
       ssh.connect(server, port=22, username='user', password='pass')
       channel = ssh.invoke_shell()

   except paramiko.AuthenticationException:
       print("Authentication failed, please verify your credentials: %s")
   except paramiko.SSHException as sshException:
       print("Unable to establish SSH connection: %s" % sshException)
   except paramiko.BadHostKeyException as badHostKeyException:
       print("Unable to verify server's host key: %s" % badHostKeyException)
   except Exception as e:
       print(e.args)
   command = ['command1','command2','command3','command4','command5','command6','command7']

   i=0
   for commands in command: 
       if i == 6:
           channel.send(command[i]+'\n')
           print("**Backup started**")
           while not channel.recv_ready():#Wait for the server to read and respond
               time.sleep(10)
           time.sleep(240)
           print("**Backup completed**")
           output2 = channel.recv(9999)    
           print(output2.decode('utf-8'))  
           txtOutput.insert(END,output2)
           txtOutput.update_idletasks()#update the output one line at time

       else:
            channel.send(command[i] + '\n') 
            print(commands + "command has started**")#display command and press enter
            while not channel.recv_ready(): #Wait for the server to read and respond
               time.sleep(3)
            time.sleep(1)
            print(commands + "command has ended**")#wait enough for writing to (hopefully) be finished
            output = channel.recv(9999) #read in
            print(output.decode('utf-8'))  
            txtOutput.insert(END,output.decode('utf-8'))
            txtOutput.update_idletasks()#update the output one line at time


    i+=1

print("Completed we will now close connection!!")
ssh.close()  

1 个答案:

答案 0 :(得分:0)

我不确定这是否可以解决问题,但是这就是我将sleep替换为after的方式。我已经将for循环拆分为几个函数。 send_cmd(i)开始执行命令i,然后启动check,该命令定期检查服务器是否准备就绪,然后安排输出提取。

def cms():
    canvas = Canvas(page3, relief = FLAT, background = "#D2D2D2", width = 694, height = 120)
    canvas.pack()
    txtOutput = Text(canvas, wrap = NONE, height =14, width = 86, borderwidth=2)
    txtOutput.pack()
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(server, port=22, username='user', password='pass')
        channel = ssh.invoke_shell()

    except paramiko.AuthenticationException:
        print("Authentication failed, please verify your credentials: %s")
    except paramiko.SSHException as sshException:
        print("Unable to establish SSH connection: %s" % sshException)
    except paramiko.BadHostKeyException as badHostKeyException:
        print("Unable to verify server's host key: %s" % badHostKeyException)
    except Exception as e:
        print(e.args)

    command = ['command1','command2','command3','command4','command5','command6','command7','command8']

    def send_cmd(i):
        if i == 6:
            print("**Backup started**")
            channel.send(command[i]+'\n')
            check2()
        else:
            print(command[i] + "command has started**")
            channel.send(command[i]+'\n')
            check1(i)


    def check1(i):
        if not channel.recv_ready():
            txtOutput.after(3000, check1, i)  # wait 3s and re-check
        else:  # server is ready, wait for execution to end and fetch output
            txtOutput.after(1000, get, command[i] + "command has ended**", i)


    def check2():
        if not channel.recv_ready():
            txtOutput.after(10000, check2)  # wait 3s and re-check
        else:  # server is ready, wait for execution to end and fetch output
            txtOutput.after(240000, get, "**Backup completed**", 6)

    def get(msg, i):
        print(msg)
        output = channel.recv(9999) #read in
        print(output.decode('utf-8'))
        txtOutput.insert(END, output.decode('utf-8'))
        if i < len(command) - 1:
            send_cmd(i + 1)  # launch next command
        else:  # no more command to launch, close ssh
            ssh.close()

    send_cmd(0)