应站内兄弟#近水楼台#的要求,吧之前发的代码加了注释,因此这个也就算不上什么文章了,新坛装老酒罢了。所以我就闲扯两句,最近无聊心血来潮下了一个MS VS2022,以为C#会继承C/C++的很多东西,我中学是自学的第一个编程语言就是C。结果……边查边写边玩的过程中发现C#和C/C++唯一的关系就是名字里有C……
无聊的我写了个IPv4的子网计算器,还没研究IPv6,所有只能算是半成品,需要源码的单独找我吧,程序也可以找我要。 .net4.8可运行
突然顿悟了一下,现在这五花八门的各种程序语言,越来越吧一个庞大的构想,分解分解再分解,不断的给这个庞大构想制作各种小工具——自定义的函数或者类,然后一拼吧,嚯!!!成了!
#!/usr/bin/env python #Linux里的写法,用了声明这个脚本是什么语言的
# -*- coding:utf-8 -*- #用来声明字符集
import paramiko # SSH操作的主模块
import paramiko.util # 我主要用来做SSH Log用
import multiprocessing # 多进程模块
class SSHTransport(object):
def __init__(self, host, port, username, password):
# 构造函数,类调用即执行
# self。xxx是类里特有的,可以简单理解成告诉类,有self的是我自己的变量,函数,没有的都是外人的
# 一般需要在类里使用的变量我都在析构函数__init__里声明一下,暂时无法赋值的就 = None,反正Python支持隐形类型转换
# 下面4条是将传进来的参数存储到类本地的变量里
self._host = host
self._port = port
self._username = username
self._password = password
# 初始化3个用于存储SSH初始化、SFTP、SSH连接的变量
self._transport = None
self._sftp = None
self._client = None
# 调用函数:_connect()
self._connect()
def _connect(self):
# 本函数用于生成连接的套接字
# 设置SSH操作日志文件
paramiko.util.log_to_file("D:\\SSH_Connect.log")
# 初始化连接
transport = paramiko.Transport((self._host, self._port))
# 发起连接
transport.connect(username=self._username, password=self._password)
# 连接句柄存储,方便其他函数调用
self._transport = transport
def download(self, remotepath, localpath):
if self._sftp is None:
# 如果sftp没创建过套接字则创建一个,都是固定格式
self._sftp = paramiko.SFTPClient.from_transport(self._transport)
# 利用套接字_sftp的get方法下载文件,参数我都用英文写的应该比较好理解
self._sftp.get(remotepath, localpath)
def upload(self, localpath, remotepath):
if self._sftp is None:
#同上,判断创建过套接字没,没有就创建一个
self._sftp = paramiko.SFTPClient.from_transport(self._transport)
# 调用put方法上传
self._sftp.put(localpath, remotepath)
def exec_command(self, command):
if self._client is None:
# 同上,SSH套接字没创建就创建一个
# 创建客户端套接字
self._client = paramiko.SSHClient()
# 创建连接,将之前做好的连接套接字拿过来用就可以
self._client._transport = self._transport
# 发送命令,会返回三个元素的(应该是List类型的结果,没太细研究,只知道这么用),stdin是标准输入,stdout是标准输出,
# stderr是标准报错,不这样写有错误会直接咯嘣
stdin, stdout, stderr = self._client.exec_command(command)
# 声明一个list类型变量,这个类型是我超级喜欢的类型,太好用了
re = list()
for Line in stdout.readlines():
# 用循环按行读取标准输出
# 读取的文本行写入到刚刚声明的List类型变量中
# [:-1]的意思是从左边开始读取,但舍弃最右边的一个字符,这里具体的意思就是把换行符给干掉
re.append(Line[:-1])
return re
def close(self):
if self._transport:
# 如果这个套接字不是空的,逻辑值就是true的,就需要执行close关闭他,有始有终是个好习惯
self._transport.close()
if self._client:
# 同上
self._client.close()
def login_info(file_name):
# 声明变量
login_info = list()
host_info = list()
with open(file_name, "r")as f:
# with open是打开文件的一种方式,我比较喜欢这样的方式,感觉比较帅的一个打开方式
for Line in f.read().splitlines():
# 循环按行读取文件内容
match len(host_info):
# match好像是在3.8,应该是3.8版本里新加的一个关键字,拿C举例,在面向过程的代码里,三个重要的过程控制关键字类就是:
# 判断、循环、分支。这里用到的就是分支,在3.8之前是不支持的,只能用if去做替代
# 这里要做的吧用户名,密码、端口、IP四个信息读取进来,存在临时变量host_info里
case 0:
host_info.append(Line)
case 1:
host_info.append(int(Line))
case 2:
host_info.append(Line)
case 3:
host_info.append(Line)
# 存满了一套登陆信息就插入到Login_info变量里,看到了吧,我非常喜欢List类型,写的东西大量应用list类型变量
login_info.append(host_info)
# 保存了条登陆信息,host_info这个临时变量的内容就没用了,用声明的方法来初始化一下
host_info = list()
# 把登陆信息作为函数的返回值传递
return login_info
def comm_info(file_name):
# 声明list变量用来存储命令
comm_info = list()
with open(file_name, "r")as f:
# 读取存储命令的文件,方法同上,不用过多解释了,唯一不同的就是命令文件是一行一条命令,不用做4行切分
for Line in f.read().splitlines():
comm_info.append(Line)
return comm_info
class mp_start(object):
# 用来做多进程的类
def __init__(self, hosts_info):
# 构造函数
# 初始化套接字存储到conn中,host_info是调用类时传递进来的参数,前四个元素是登陆信息
conn = SSHTransport(hosts_info[0], hosts_info[1], hosts_info[2], hosts_info[3])
# 存结果的临时变量,有事list类型
re = list()
# 添加一行,记录下IP
re.append("IP Address is: " + hosts_info[0])
for comm in hosts_info[4]:
#第五个元素个List类型的元素,也就是说我吧List做成了二维的,哈哈
# 在结果中记录下命令体
re.append("---=== Command is: " + comm)
for Line in conn.exec_command(comm):
# 调用conn也就是我之前做的SSHTransport类的exec_command方法来执行命令,用for循环来按行处理结果,外层循环是循环的登陆信息
# 内层循环跑的命令集,结果就是所有的登陆信息都执行了所有的命令,当然这里我没做不对称的二维hosts_info,也就是不通的登陆信息执行
# 不同的命令集,我只做了同质化的示例
re.append(Line) # 存储结果行
# 有始有终是个好孩子
conn.close()
# 添加空行
re.append("")
# 向屏幕打印结果
for Line in re:
print(Line)
if __name__ == "__main__":
#这里就是程序的入口了
# 这条if的作用是判断下程序是被引用的,还是执行的,如果是执行的,就执行下面一段
# 声明变量,还是List类型哈
hosts_info = list()
comms_info = list()
for Line in comm_info("Command.ini"):
# 调用之前定义好的函数,吧命令都存起来
comms_info.append(Line)
for Line in login_info("LoginInfo.ini"):
# 调用定义好的函数把登陆信息都存起来这两条for是为了满足多进程要求而做的
hosts_info.append([Line[0], Line[1], Line[2], Line[3], comms_info])
with multiprocessing.Pool() as p:
# 上一条固定格式,调用多进程模块
# 下一条常用格式,mp_start是进程启动的函数, hosts_info是参数,List类型,这样灌进去,剩下的就交给命运来安排就好了
print(p.map(mp_start, hosts_info))
如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!
赞1
添加新评论0 条评论