Python作为一个编程语言,在近几年还是很火的,毕竟代码可以实现的功能还很多,也很厉害。
学生管理系统对于当前的学生来说都是学习必备,刷题必备,基本学一个语言就要做一个学生管理系统,方法无疑就是在本地创建一个txt文件然后写入以及读取其内容。然而缺点也随即出现,无论什么语言,都会极大地消磨本地内存,如果建立的学生文件过多或者文件里行数过多,也会极大占用内存,这无疑是很明显的缺点。
Paramiko 作为Python的一个第三方库,其主要包括两个核心组件: SSHClient 和 SFTPClient:
1.SSHClient 的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输(Transport),通道(Channel)及 SFTPClient 建立的方法(open_sftp),通常用于 执行远程命令 。
2.SFTPClient的作用类似与 Linux 的 sftp命令 ,是对SFTP客户端的封装,用以实现 远程文件操作 ,如 文件上传、下载、修改文件权限 等操作。
(解释来自这个网站)
其不仅支持这两个方法,还能进行远程登录连接Linux主机,对于我这个标题,无疑就是使用这个库连接服务器或者虚拟机进行操作。
注:所有方法以及原理在下面的代码中已经全部注释,主要有几点需要注意:
-1.一定要在服务器内建好绝对路径!
-2.一定注意方法中是否存在sftp或者sftp_client的变量,不然会导致提前关闭全局变量sftp或者sftp_client!导致无法循环使用!
-3.无论 -添加/修改- 还是 -查找- 或是 -删除-,一定要检查服务器路径是否绝对,是否正确,如果不正确,很有可能导致服务器错乱或者报错!
-4.如果使用虚拟机,打开/etc/sysconfig/network-scripts/ifcfg-eth0,获取到ip地址,reboot后再使用代码连接
-5.如果使用本地Linux主机,找对自己的IP地址再进行代码连接
-6.如果使用远程Linux主机,如果不用于其他用途,请一定不要使用公网IP
-7.SFTPClient的端口号是22
-8.一定加入login方法!!!
注意事项已经标注,请检查完毕再试运行代码!
第一步:部署 SSHClient 与 SFTPClient
(注:这里会用到 Paramiko 里的 Transport() 方法进行链接)
#导入相应的包
import paramiko
import os
import sys
#设置登录服务器参数
hostname = "(ip.ip.ip.ip)"
#因为使用的文件传输协议,所以使用22端口
port = 22
username = "name"
password = "password"
'''
paramiko的参数设置是hostname(服务器或虚拟机ip地址),port(端口号,传输文件一般使用22端口),username password(登录服务器的用户名和密码)
'''
#初始化ssh
'''
初始化SSHClient里,先初始化核心方法SSHClient(),调用里面的connect()将刚刚的参数传进来,进行连接服务器
'''
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname, port, username, password, compress=True)
#初始化transport
'''
在transport里,传入ip端口以及用户名密码进行connect连接
'''
transport = paramiko.Transport((hostname, 22))
transport.connect(username = username, password = password)
#初始化sftp(即调用SFTPClient)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp_client = client.open_sftp()
'''
这里并没有使用两种方法而多此一举,各有各的用法
'''
第二步:分明函数作用(并不使用class定义类)
def chooce():
pass
def remove_student():
pass
def find_student():
pass
def add_student():
pass
def login():
pass
if __name__ == '__main__':
login()
'''
这里分开了几个方法,选择界面、删除学生、查找学生、添加学生、登录窗口
-设置登录窗口主要是因为毕竟是因为这个库可以操作服务器,可以用几个方法进行删除或者上传文件的操作,看得见日志可以ban IP但是还是小心为好。
'''
第三步:部署login()
def login():
try:
print('***连接成功***\n')
#建立读取用户名和密码的列表,将服务器内文件的字符遍历进列表
name = []
psw = []
#因为已经有了sftp_client的全局变量(调用方法),这里可以注释掉
#sftp_client = client.open_sftp()
#读取服务器内的文件
name_file = sftp_client.open("/student/login/name.txt")
psw_file = sftp_client.open("/student/login/password.txt")
try:
#如果可以读取到(只要连接上,这里一般是都可以读取到的,except存不存在主要是看主机可不可以连接成功)
#使用for循环读取登录程序的用户名和密码,将其遍历进列表
for p in psw_file:
psw.append(p)
for n in name_file:
name.append(n)
finally:
#finally里可以是pass,不需要关闭文件流,如果操作存在强迫症,完全可以添加文件流的关闭
#name_file.close()
#psw_file.close()
pass
#输入登录程序的用户名和密码
user = input("用户名:")
user_psw = input("密码:")
#进行判定是否登录成功
if(len(user) == 0 or len(user_psw) == 0):
print("请不要输入为空!")
login()
elif(user == name[0] and user_psw == psw[0]):
print("登陆成功!\n")
chooce()
elif(user != name[0]):
print("用户名错误!")
login()
elif(user_psw != psw[0]):
print("密码错误!")
login()
except:
print(***连接失败***)
第三步:部署chooce()
def chooce():
#这里比较简单,不做过多介绍
print('***请选择您的操作***\n')
print('**1.添加/修改 学生**')
print('**2.查找学生**')
print('**3.删除学生**')
print('**4.退出程序**')
print('\n***请选择您的操作***\n')
answer = int(input('您的选择:'))
if(answer == 1):
add_student()
elif(answer == 2):
find_student()
elif(answer == 3):
remove_student()
elif(answer == 4):
print('\n***感谢您的使用(By WangPeiXi)')
sys.exit(0)
sftp.close()
else:
print('请输入正确的选择!')
chooce()
第四步:部署add_student()
def add_student():
print("\n---添加/修改 学生---\n")
print("---退回请输入‘exit’---\n")
student_name = input("输入学生姓名:")
#这里一样因为已经有了sftp_client的全局变量(调用方法),这里可以注释掉
#sftp_client = client.open_sftp()
if(len(student_name) == 0):
print("请不要输入为空!")
add_student()
elif(student_name == 'exit'):
print('即将返回!\n')
chooce()
else:
#这里运用到了os库,原因是因为我没试过直接读取服务器里的文件行,原理是在本地生成文件然后上传指定目录再删除本地文件
#local_file(本地文件)//remote_file(服务器绝对目录!!!一定是绝对目录以及文件名!!!)
local_file = student_name + '.txt'
remote_path = '/student/students/' + student_name + '.txt'
with open(local_file,'a') as stu:
#这里在本地写入文件内容,如果可以还可以加入其他内容
stu_class = input("输入班级:")
stu_age = input("输入年龄:")
stu_home = input("输入籍贯:")
stu_id = input("输入学号:")
stu.write(student_name + '\n')
stu.write(stu_class + '\n')
stu.write(stu_age + '\n')
stu.write(stu_home + '\n')
stu.write(stu_id)
#一定不要忘记关闭文件流!不然会报错正在使用改文件!
stu.close()
#读取的时候会将换符行(\n)一块读取
try:
#如果成功的话,执行SFTPClient里的put函数,将本地文件上传到服务器的绝对目录
#这里有一个小小的bug,现在还没有解决,就是如果服务器内存在文件,如果两次上传了一个一模一样的文件名,那么第一个文件(也就是第一次上传的文件)会被第二个文件覆盖,无论文件名还是内容
sftp.put(local_file,remote_path)
except Exception as e:
#这里运用到sys.exit(1)主要是以一个失败的方式关闭
print("上传失败")
sys.exit(1)
finally:
#可以注释掉这一句,如果add_student()里没有局部变量sftp则一定要注释掉这一句!
#sftp.close()
pass
#删除本地文件
os.remove(local_file)
print("添加完成!\n")
add_student()
第四步:部署find_student()
def find_student():
print('\n---查找学生---\n')
print("---退回请输入‘exit’---\n")
student_name = input('输入学生姓名:')
#这里一样因为已经有了sftp_client的全局变量(调用方法),这里可以注释掉
#sftp_client = client.open_sftp()
#这里一样运用到了os库,原因是因为我没试过直接读取服务器里的文件行,原理是将服务器的文件里下载到本地然后逐行读取再删除本地文件
#local_file(本地文件)//remote_file(服务器绝对目录!!!一定是绝对目录以及文件名!!!)
#如果没什么问题,可以将local_file和remote_file放在方法之前作为全局变量
local_file = student_name + '.txt'
remote_path = '/student/students/' + student_name + '.txt'
if(len(student_name) == 0):
print('请不要输入为空!')
find_student()
elif(student_name == 'exit'):
print('即将返回!\n')
chooce()
try:
#如果成功则执行sftp里的get方法,将服务器文件下载到本地
sftp.get(remote_path,local_file)
#这里注意encoding的编码
with open(local_file,'r',encoding='gbk') as fstu:
#读取文件每行
stu = fstu.readlines()
print('\n***已经找到该学生***\n')
print('姓名:' + stu[0])
print('班级:' + stu[1])
print('年龄:' + stu[2])
print('籍贯:' + stu[3])
print('学号:' + stu[4])
#一定关闭文件流!不然无法删除本地文件!
fstu.close()
except:
print('\n---未找到该学生---\n')
finally:
#这里也一样可以注释掉这一句,如果find_student()里没有局部变量sftp则一定要注释掉这一句!
#sftp.close()
#stu.close()
pass
#最后删除本地文件
os.remove(local_file)
find_student()
第五步:部署remove_student()
def remove_student():
print("\n---删除学生---\n")
print("---退回请输入‘exit’---\n")
student_name = input("输入学生姓名:")
#这里运用的方法和之前不一样,是执行transport里的stdin方法,在控制台执行一个“sudo -i rm -f”语句进行删除。
if(len(student_name) == 0):
print('请不要输入为空!')
remove_student()
elif(student_name == 'exit'):
print('即将返回!\n')
chooce()
else:
#这里也必须是绝对路径,如果出错,那么可能删除其他文件!
remote_path = '/student/students/' + student_name + '.txt'
try:
#如果成功执行命令
stdin,stdout,stderr=client.exec_command('sudo -i rm -f ' + remote_path,get_pty=True)
stdin.write("test\n")
except:
#连接到文件之后失败的原因只有文件不存在,换个方式理解也就是 -该学生不存在-
print('---该学生不存在---\n')
remove_student()
finally:
#这里注释以及不注释都没什么区别
#stdin.close()
print('删除成功!\n')
remove_student()
第六步:添加一个程序入口
if __name__ == '__mian__':
login()
最后我把文件模板上传一份,你们可以下载,提取码是gatz。如果有什么建议或者bug可以及时分享一下,哈哈哈一起学习嘛!