构建一个将文件上传服务器的小工具
import os
import re
import time
import paramiko
import threading
import tkinter.filedialog
from tkinter import *
from scp import SCPClient
from paramiko.ssh_exception import NoValidConnectionsError,AuthenticationException
# 进程保护
class MyThread(threading.Thread):
def __init__(self, func, *args):
super().__init__()
self.func = func
self.args = args
self.setDaemon(True)
self.start() # 在这里开始
def run(self):
self.func(*self.args)
class windowGui():
def __init__(self, window):
self.window = window
self.CheckVar1 = StringVar()
def myGui(self):
win = self.window
win.title('Linux文件上传小工具 v0.3')
win.geometry('600x600+100+100')
self.title001 = Label(win, text='请输入服务器IP:').place(x=10, y=10)
self.title002 = Label(win, text='请输入服务器账号:').place(x=10, y=40)
self.title003 = Label(win, text='请输入服务器密码:').place(x=10, y=70)
self.title004 = Label(win, text='请输入服务器目录:').place(x=10, y=100)
self.text001 = Entry(win, width=50, bd=1, highlightcolor='DeepSkyBlue', highlightthickness=1) # 原始数据输入框
self.text001.place(x=120, y=12, show=None)
self.text002 = Entry(win, width=50, bd=1, highlightcolor='DeepSkyBlue', highlightthickness=1) # 原始数据输入框
self.text002.place(x=120, y=42, show=None)
self.text003 = Entry(win, width=50, bd=1, highlightcolor='DeepSkyBlue', highlightthickness=1) # 原始数据输入框
self.text003.place(x=120, y=72, show=None)
self.text004 = Entry(win, width=50, bd=1, highlightcolor='DeepSkyBlue', highlightthickness=1) # 原始数据输入框
self.text004.place(x=120, y=102, show=None)
self.text005 = Entry(win, width=50, highlightcolor='DeepSkyBlue', highlightthickness=1, textvariable=self.CheckVar1) # 原始数据输入框
self.text005.place(x=120, y=135, show=None)
self.text009 = Text(win, width=80, height=25)
self.text009.place(x=20, y=250)
self.input001 = Button(win, text='确定', width=80, height=1, bd=1, command=lambda:MyThread(self.set_input001))
self.input001.place(x=15, y=170)
self.input002 = Button(win, text='选择文件', width=10, height=1, bd=1, command=self.set_input002)
self.input002.place(x=500, y=135)
self.input003 = Button(win, text='zip文件解压', width=10, height=1, bd=1, command=self.unzip_file)
self.input003.place(x=200, y=210)
self.input004 = Button(win, text='tar文件解压', width=10, height=1, bd=1, command=self.unzip_file)
self.input004.place(x=300, y=210)
def set_input001(self):
self.get_input()
def set_input002(self):
# 获取本地文件
self.selectFileName = tkinter.filedialog.askopenfilename(title='选择文件')
# 将文件路径写入对应的文本框
self.CheckVar1.set(self.selectFileName)
# 功能函数
def get_input(self):
# 正则校验输入的IP是否是合法的IP地址
rp = re.compile(r'^((?:[0-9]{1,3}\.){3}[0-9]{1,3}$)')
# 获取text001输入框的值并去除前后空格
ip001 = self.text001.get().strip()
# 使用re.findall()进行校验
url001 = re.findall(rp, str(ip001))
# 正则匹配的出来的是一个列表,需要重新提取一遍
host = url001[0]
username = self.text002.get().strip()
password = self.text003.get().strip()
dtl = self.text004.get().strip()
All = [self.text001, self.text002, self.text003, self.text004, self.text005]
# 创建一个ssh的客户端,用来连接服务器
ssh_client = paramiko.SSHClient()
# 创建一个ssh的白名单
know_host = paramiko.AutoAddPolicy()
# 加载创建的白名单
ssh_client.set_missing_host_key_policy(know_host)
# 连接服务器
ssh_client.connect(host, 22, username, password)
self.ssh_client = ssh_client
# 如果IP存在
if host:
# 输入框禁用
for i in All:
i.config(state=DISABLED)
time.sleep(1)
# 清空文本框内容
self.text009.delete(1.0, END)
# 打印输出
self.text009.insert(1.0, '服务器IP为{}'.format(host))
# 建立Linux链接
client = SCPClient(self.ssh_client.get_transport(), buff_size=1024 * 64, socket_timeout=15.0)
try:
# 上传文件
client.put(self.selectFileName, dtl)
data = "{} 文件上传完成".format(self.selectFileName)
# 打印输出
self.text009.insert(1.0, data+'\n')
print("\r", " %s 文件上传完成" % self.selectFileName.split(os.sep)[-1]+'\n', end='', flush=True)
dtl += self.selectFileName.split(os.sep)[-1]
# 输入框启用
for j in All:
j.config(state=NORMAL)
self.ssh_client.close()
except AuthenticationException as e:
print(e)
print("系统找不到指定文件" + self.selectFileName)
else:
self.text009.delete(1.0, END)
self.text009.insert(1.0, '您输入的IP有误,请重新输入!')
print('您输入的IP有误,请重新输入!')
# 功能函数
def unzip_file(self):
"""
:param remote_path:
:return:
stdin 标准格式的输入,是一个写权限的文件对象
stdout 标准格式的输出,是一个读权限的文件对象
stderr 标准格式的错误,是一个写权限的文件对象
"""
try:
# 获取文件名称
like = os.path.split(self.selectFileName)[1].strip()
# 获取Linux路径
extract_files_into = self.text004.get().strip()
# 判断解压方式为unzip
if self.input003:
print("\r", '正在解压 · · · '+'\n', end='', flush=True)
self.text009.insert(1.0, '正在解压 · · · '+'\n')
# 执行命令(进入Linux对应目录下,执行zip解压,显示当前目录信息)
stdin, stdout, stderr = self.ssh_client.exec_command('cd {}'.format(extract_files_into)+"&& unzip -n %s/%s" % (extract_files_into, like) + '&& ls -l')
l = stdout.read().decode()
print(l)
print("解压完成")
self.text009.insert(1.0, l + "解压完成" + '\n')
# 判断解压方式为tar
elif self.input004:
print("\r", '正在解压 · · · '+'\n', end='', flush=True)
self.text009.insert(1.0, '正在解压 · · · ' + '\n')
# 执行命令(进入Linux对应目录下,执行tar解压,显示当前目录信息)
stdin, stdout, stderr = self.ssh_client.exec_command('cd {}'.format(extract_files_into) + "&& tar -zvf %s %s" % (extract_files_into, like) + '&& ls -l')
l = stdout.read().decode()
print(l)
print("解压完成")
self.text009.insert(1.0, l + '\n' + "解压完成" + '\n')
else:
pass
except:
print("文件格式异常,解压失败")
def set_start(self, GUI):
GUI.myGui()
# 保持窗口运行
window.mainloop()
if __name__ == "__main__":
window = Tk()
html = windowGui(window)
html.set_start(html)
# window.mainloop()