我目前正在构建脚本以自动执行备份过程。该脚本可以很好地将输出内容从外壳程序转储到文本框中,直到第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()
答案 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)