python作业类Fabric主机管理程序开发(第九周)
作业需求:
1. 运行程序列出主机组或者主机列表
2. 选择指定主机或主机组
3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)
4. 充分使用多线程或多进程
5. 不同主机的用户名密码、端口可以不同
思路解析:
1. 运用paramiko模块里的command和sftp方法执行命令传输文件
2. 指定主机和主机组,使用字典读取字典信息里的组和服务器信息,列出主机组和主机列表
3. 用threading模块控制paramiko模块里的command和sftp方法执行命令传输文件
4. 字典信息可以添加修改
程序核心代码
README
作者:yaobin
版本:简单Ftp示例版本 v0.1
开发环境: python3.6 程序介绍:
类 Fabric 主机管理程序开发:
1. 运行程序列出主机组或者主机列表
2. 选择指定主机或主机组
3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)
4. 充分使用多线程或多进程
5. 不同主机的用户名密码、端口可以不同 使用说明: /bin/fortress_machine ├─bin
│ fortress_machine.py #程序主目录
│ __init__.py
│
├─conf
│ │ server_list
│ │ setting.py
│ │ __init__.py
│ │
│
├─core
│ │ add_machine.py #添加server字典程序
│ │ basic_dict.py #初始化字典程序
│ │ fortress_main.py #交互程序
│ │ group_paramiko.py #组管理交互程序
│ │ group_sftp.py #组上传/下载交互程序
│ │ server_paramiko.py #server管理交互程序
│ │ server_sftp.py #server上传/下载交互程序
│ │ __init__.py
│ │
│ └─__pycache__
├─db
│ ├─download #文件下载目录
│ └─upload #文件上传目录
│ AutoResponder.xml
│
├─logs
│ __init__.py
│
└─model
│ prettytable.py PrettyTable模块
│ __init__.py
│
├─paramiko paramiko 模块
│
└─__pycache__
prettytable.cpython-36.pyc
__init__.cpython-36.pyc
add_machine.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''添加主机和主机组类'''
import os
import sys
import re
import pickle
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from model.prettytable import PrettyTable class add_machine_list(object):
'''
add_machine类
'''
def __init__(self):
'''
构造函数
:param dict_file_object 字典文件
'''
with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) #server_list_dict服务器字典变量
dict_file_object.close() def add_group_object(self):
'''
添加新群组新群组server字典函数
:return:
'''
self.view_server()
self.group_server_name = input('请输入要添加的组名称>>>>>>>>:') # 组名key input 打印组内机器
if self.group_server_name in self.server_list_dict['machine']:
print('%s组已经存在,请重新输入...' % self.group_server_name)
self.add_group_object()
else:
self.add_new_group_server(self.group_server_name)
self.group_server_object = {self.server_name: {'ip': self.server_name, 'port': self.server_port,
'username': self.server_username,
'passwd': self.server_passwd}} # 添加group
self.server_list_dict['machine'][self.group_server_name] = self.group_server_object
with open(setting.server_list_path, 'wb') as dict_file_object:
dict_file_object.write(pickle.dumps(self.server_list_dict))
dict_file_object.close()
self.view_server() def add_server_object(self):
'''
添加组内server字典函数
:return:
'''
self.view_server()
self.group_server_name = input('请输入要添加server的组>>>>>>>>:')
if self.group_server_name in self.server_list_dict['machine']:
self.add_server(self.group_server_name)
server_object = {'ip': self.server_name, 'port': self.server_port, 'username': self.server_username,
'passwd': self.server_passwd} # 添加server
self.server_list_dict['machine'][self.group_server_name][self.server_name] = server_object
with open(setting.server_list_path, 'wb') as dict_file_object:
dict_file_object.write(pickle.dumps(self.server_list_dict))
dict_file_object.close()
print('Server add done please check')
self.view_server()
else:
print('要添加server的组%s不存在请重新输入' % self.group_server_name)
self.add_server_object() def add_server(self,group_server_name):
'''
添加组内server函数
:param:group_server_name: groupname
:return:
'''
self.view_server()
try:
self.server_name = input('请输入要添加的server ip>>>>>>>>:') # 添加server 机器
server_name_re_rr = \
re.compile("^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + "" # 判断ip正则
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$")
res = server_name_re_rr.findall(self.server_name)
if res[0]: #如果有值判断是否正常
if self.server_name not in self.server_list_dict['machine'][self.group_server_name]:
while True:
try:
self.server_port = input('请输入要添加的server port>>>>>>>>:') # 判断port 1-65535
if int(self.server_port) >= 22 and int(self.server_port) < 65535:
self.server_username = input('请输入要添加的server username>>>>>>>>:')
self.server_passwd = input('请输入要添加的server passwd>>>>>>>>:')
break # 正常取完变量后才能结束
else:
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
except ValueError: # 如果出现valueerror
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
else:
print('%s已经存在,请重新输入' % self.server_name)
self.add_server(self.group_server_name)
except IndexError as e:
print('%s输入不正确,请输入正确的ip地址'%self.server_name)
self.add_server(self.group_server_name) def add_new_group_server(self,group_server_name):
'''
添加新组server函数
:param group_server_name:要添加的组名
:return:
'''
self.view_server()
try:
self.server_name = input('请输入要添加的server ip>>>>>>>>:') # 添加server 机器
server_name_re_rr = \
re.compile("^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + "" # 判断ip正则
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$")
res = server_name_re_rr.findall(self.server_name)
if res[0]: # 如果有值判断是否正常
while True:
try:
self.server_port = input('请输入要添加的server port>>>>>>>>:') # 判断port 1-65535
if int(self.server_port) >= 22 and int(self.server_port) < 65535:
self.server_username = input('请输入要添加的server username>>>>>>>>:')
self.server_passwd = input('请输入要添加的server passwd>>>>>>>>:')
break # 正常取完变量后才能结束
else:
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
except ValueError: # 如果出现valueerror
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
except IndexError as e:
print('%s输入不正确,请输入正确的ip地址' % self.server_name)
self.add_server(self.group_server_name)
self.view_server() def modifi_group(self,group,ip,port,username,passwd):
'''
修改server群组名和server群组内机器的方法,暂不做处理
:param group:
:param ip:
:param port:
:param username:
:param passwd:
:return:
''' def view_server(self):
'''
查看server函数
:return:
'''
view_ip = PrettyTable(['Group.', 'Ip', ])
for i in self.server_list_dict['machine']:
for s in self.server_list_dict['machine'][i]:
view_ip.add_row([i, s])
print('%s' % view_ip)
basic_dict.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os
import sys
import pickle
from conf import setting
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
def basic_dict():
'''
初始化程序字典
:return:
'''
add_machine_dict = {'machine':{'group1':{'192.168.84.130':
{'ip':'192.168.84.130','port':'','username':'root','passwd':''}}}}
with open(setting.server_list_path,'wb') as dict_file_object:
dict_file_object.write(pickle.dumps(add_machine_dict))
dict_file_object.close()
fortress_main.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''主交互程序'''
import os
import sys base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from model.prettytable import PrettyTable
from core import add_machine
from core import group_paramiko
from core import server_paramiko class fortress_machine(object):
'''
类Fabric主机管理程序
'''
def __init__(self):
'''
构造方法
'''
pass def cmd_choice(self):
'''
帮助函数
:return:
'''
cmd_choice = PrettyTable(['No.', '说明'])
cmd_choice.add_row(['', '组管理'])
cmd_choice.add_row(['', '主机管理'])
cmd_choice.add_row(['', ' 添加server'])
cmd_choice.add_row(['', ' 添加group'])
cmd_choice.add_row(['', ' 查看server'])
cmd_choice.add_row(['', '退出程序'])
print(cmd_choice) def user_choice(self):
'''
用户选择函数
:return:
'''
while True:
self.cmd_choice()
user_choice = input('Please input your choice>>>>>>:')
if user_choice == '':
print('Welcome ,The list of hosts is as follows ')
group_paramiko.fortress_main().choice()
if user_choice == '':
print('Welcome ,The list of hosts is as follows ')
server_paramiko.fortress_main().choice()
elif user_choice == '':
add_machine.add_machine_list().add_server_object()
elif user_choice == '':
add_machine.add_machine_list().add_add_group_object()
elif user_choice == '' or user_choice == 'q' or user_choice == 'exit':
add_machine.add_machine_list().view_server()
elif user_choice == '' or user_choice == 'q' or user_choice == 'exit':
sys.exit('程序退出')
else:
print('disallow %s please input again'%user_choice)
group_paramiko.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''类Fabric主机管理交互程序'''
import os
import sys
import pickle
import threading
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from core import add_machine
from model import paramiko
from core import group_sftp
from model.prettytable import PrettyTable class fortress_main(object):
'''fortress类'''
def __init__(self):
'''
构造函数
'''
self.semaphore = threading.BoundedSemaphore(1)
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close() def choice(self):
'''
输入函数
:return:
'''
add_machine.add_machine_list().view_server()
self.group_input = input('Please input group name >>>>>>>>:')
if self.group_input in self.server_list_dict['machine']:
self.group_send_command()
else:
print('There is no group named %s ' % self.group_input)
self.choice()
return self.group_input def ssh_group_cmd(self,command):
'''
组管理函数
:return:
'''
for s in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][s]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][s]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][s]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][s]['passwd']
self.ssh.connect(self.server_ip, self.server_port, self.server_username, self.server_passwd)
self.t1 = threading.Thread(target=self.ssh_command(command))
self.t1.setDaemon(True)
self.t1.start() def ssh_connect(self,ip,port,username,passwd):
'''
批量激活主机函数
:param ip:
:param port:
:param username:
:param passwd:
:return:
'''
self.t = threading.Thread(target=self.ssh.connect,args=(ip, port, username,passwd))#开启线程
self.t.setDaemon(True) #设置守护线程
self.t.start() def ssh_command(self,command):
'''
发送ssh服务器命令
:param command:
:return:
'''
stdin, stdout, stderr = self.ssh.exec_command(command)
res, err = stdout.read(), stderr.read() # 定义俩个变量
self.semaphore.acquire()
result = res if res else err # 定义三元运算
print((self.server_ip).center(50,'-'))
print(result.decode())
self.ssh.close()
self.semaphore.release() def group_send_command(self):
'''
group发送指令函数
:return:
\ '''
while True:
command_input = input('please input command,input help for help >>>>>>>>:').strip() # 这里要调用命令
if len(command_input) == 0:
pass
elif len(command_input.split()) == 1:
if command_input == 'help':
self.help_page()
elif command_input == 'exit':
self.ssh.close()
exit()
else:
self.ssh_group_cmd(command_input)
elif len(command_input.split()) >= 2: # 命令分割
cmd_split = command_input.split()[0]
self.fileobject = command_input.split()[1] # 获取文件路径
self.filename = self.fileobject.split('/')[-1] # 获取文件名
if cmd_split == 'get': #未处理
group_sftp.group_ftp(self.group_input,self.fileobject,self.filename).download()
elif cmd_split == 'put':#未处理
group_sftp.group_ftp(self.group_input,self.fileobject,self.filename).upload()
elif cmd_split == 'help':
self.help_page()
else:
self.ssh_group_cmd(command_input)
else:
print('unsupported command')
self.help_page() def help_page(self):
'''
help页面
:return:
'''
help_page = PrettyTable(['Command.', 'Explain', ])
help_page.add_row(['get filename', ' download file'])
help_page.add_row(['put /path/filename', 'upload file'])
help_page.add_row(['other', 'send command'])
help_page.add_row(['exit ', 'exit program'])
help_page.add_row(['help ', ''])
print('%s' % help_page)
group_sftp.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os
import sys
import pickle
import platform
import threading
import time,random
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from model import paramiko class group_ftp(object):
'''
serverftp类
'''
def __init__(self,group_input,fileobject,filename):
'''
构造函数
:param group_input:
:param server_input:
:param fileobject:
'''
self.group_input = group_input
self.fileobject = fileobject
self.filename = filename with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close() def upload(self):
'''
上传函数
:param command:
:return:
'''
try:
os.chdir(setting.upload_path)
for s in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][s]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][s]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][s]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][s]['passwd']
self.transport = paramiko.Transport((self.server_ip, self.server_port))
self.transport.connect(username=self.server_username, password=self.server_passwd)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
t = threading.Thread(target=self.sftp.put, args=(self.filename, self.fileobject))
t.start()
except FileNotFoundError as e:
print('system error ', e) def download(self):
'''
下载函数
:param
:return:
'''
os.chdir(setting.download_path)
for s in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][s]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][s]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][s]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][s]['passwd']
self.transport = paramiko.Transport((self.server_ip, self.server_port))
self.transport.connect(username=self.server_username, password=self.server_passwd)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
try:
if platform.system() == 'Windows':
#self.sftp.get(self.fileobject, (setting.download_path + '\\' + self.filename))
t = threading.Thread(target=self.sftp.get,args=(self.fileobject, (setting.download_path + '\\' + self.filename)))
t.start()
#time.sleep(10)
else:
#self.sftp.get(self.fileobject, (setting.download_path + '/' + self.filename))
t = threading.Thread(target=self.sftp.get,
args=(self.fileobject, (setting.download_path + '\\' + self.filename)))
t.start()
if os.path.exists(setting.download_path + '\\' + self.filename):
print('file download complete')
else:
print('file download error')
except FileNotFoundError as e:
print('system error ', e)
os.remove(self.filename)
server_paramiko.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''类Fabric主机管理交互程序'''
import os
import sys
import pickle
import threading
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from core import add_machine
from core import server_sftp
from model import paramiko
from model.prettytable import PrettyTable class fortress_main(object):
'''fortress类''' def __init__(self):
'''
构造函数
'''
self.semaphore = threading.BoundedSemaphore(1)
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close() def choice(self):
'''
模式选择函数
:return:
'''
add_machine.add_machine_list().view_server()
self.group_input = input('Please input group name >>>>>>>>:')
self.server_input = input('Please input the server name you want to manage >>>>>>>>:')
if self.group_input in self.server_list_dict['machine']:
if self.server_input in self.server_list_dict['machine'][self.group_input]:
self.server_send_command()
else:
print('There is no server named %s please input again' % self.server_input)
self.choice()
else:
print('There is no group named %s please input again' % self.group_input)
self.choice()
return self.group_input,self.server_input def ssh_server_cmd(self,command):
'''
server管理函数
:return:
'''
self.server_ip = self.server_list_dict['machine'][self.group_input][self.server_input]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][self.server_input]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][self.server_input]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][self.server_input]['passwd']
self.ssh.connect(self.server_ip, self.server_port, self.server_username, self.server_passwd)
self.t1 = threading.Thread(target=self.ssh_command(command))
self.t1.setDaemon(True)
self.t1.start()
print('thread name is %s' % self.t1.getName()) def ssh_connect(self,ip,port,username,passwd):
'''
批量激活主机函数
:param ip:
:param port:
:param username:
:param passwd:
:return:
'''
self.t = threading.Thread(target=self.ssh.connect,args=(ip, port, username,passwd))#开启线程
self.t.setDaemon(True) #设置守护线程
self.t.start() def ssh_command(self,command):
'''
发送ssh服务器命令
:param command:
:return:
'''
stdin, stdout, stderr = self.ssh.exec_command(command)
res, err = stdout.read(), stderr.read() # 定义俩个变量
self.semaphore.acquire()
result = res if res else err # 定义三元运算
print((self.server_ip).center(50,'-'))
print(result.decode())
self.ssh.close()
self.semaphore.release() def server_send_command(self):
'''
server发送指令函数
:return:
'''
while True:
command_input = input('please input command,input help for help >>>>>>>>:').strip() # 这里要调用命令
if len(command_input) == 0:
pass
elif len(command_input.split()) == 1:
if command_input == 'help':
self.help_page()
elif command_input == 'exit':
self.ssh.close()
exit()
else:
self.ssh_server_cmd(command_input)
elif len(command_input.split()) >= 2: # 命令分割
cmd_split = command_input.split()[0]
self.fileobject = command_input.split()[1] # 获取文件路径
self.filename = self.fileobject.split('/')[-1] # 获取文件名
print(self.fileobject)
print(self.filename)
if cmd_split == 'get':
server_sftp.server_ftp(self.group_input,self.server_input,self.fileobject, self.filename).download()
elif cmd_split == 'put':
server_sftp.server_ftp(self.group_input,self.server_input,self.fileobject, self.filename).upload()
elif cmd_split == 'help':
self.help_page()
else:
self.ssh_server_cmd(command_input)
else:
print('unsupported command')
self.help_page() def help_page(self):
'''
help页面
:return:
'''
help_page = PrettyTable(['Command.', 'Explain', ])
help_page.add_row(['get filename', ' download file'])
help_page.add_row(['put /path/filename', 'upload file'])
help_page.add_row(['other', 'send command'])
help_page.add_row(['exit ', 'exit program'])
help_page.add_row(['help ', ''])
print('%s' % help_page)
server_sftp.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao import os
import sys
import pickle, json
import platform
import threading
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from model import paramiko class server_ftp(object):
'''
serverftp类
'''
def __init__(self, group_input,server_input,fileobject,filename):
'''
构造函数
:param group_input:
:param server_input:
:param fileobject:
'''
self.group_input = group_input
self.server_input = server_input
self.fileobject = fileobject
self.filename = filename with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close()
if self.group_input in self.server_list_dict['machine']:
if self.server_input in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][self.server_input]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][self.server_input]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][self.server_input]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][self.server_input]['passwd']
self.transport = paramiko.Transport((self.server_ip, self.server_port))
self.transport.connect(username=self.server_username, password=self.server_passwd)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
else:
pass
else:
print('not allow')
def upload(self):
'''
上传函数
:param command:
:return:
'''
try:
os.chdir(setting.upload_path)
self.sftp.put(self.filename,self.fileobject)
except FileNotFoundError as e:
print('system error ', e) def download(self):
'''
下载函数
:param
:return:
'''
os.chdir(setting.download_path)
try:
if platform.system() == 'Windows':
self.sftp.get(self.fileobject, (setting.download_path + '\\' + self.filename))
else:
self.sftp.get(self.fileobject, (setting.download_path + '/' + self.filename))
if os.path.exists(setting.download_path + '\\' + self.filename):
print('file download complete')
else:
print('file download error')
except FileNotFoundError as e:
print('system error ', e)
os.remove(self.filename)
setting.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''配置文件'''
import os
import sys
import platform base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir) if platform.system() == 'Windows':
server_list_path = os.path.dirname(os.path.abspath(__file__))+'\\'+'server_list'#主机列表字典路径变量
server_dict_path = os.path.dirname(os.path.abspath(__file__)) + '\\' + 'server_dict'
download_path = (base_dir+'\\'+'db\download') #下载路径变量
upload_path = (base_dir + '\\' + 'db\\upload') #上传路径变量
else:
server_list_path = os.path.dirname(os.path.abspath(__file__)) + '/' + 'server_list'
server_dict_path = os.path.dirname(os.path.abspath(__file__)) + '/' + 'server_dict'
download_path = (base_dir + '/' + 'db\download')
upload_path = (base_dir + '/' + 'db\\upload')
程序测试样图




python作业类Fabric主机管理程序开发(第九周)的更多相关文章
- python第五十二天---第九周作业 类 Fabric 主机管理程序
类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)4. 充分使用多线程或多进程5. 不同 ...
- python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)
类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...
- python 学习分享-实战篇类 Fabric 主机管理程序开发
# 类 Fabric 主机管理程序开发: # 1. 运行程序列出主机组或者主机列表 # 2. 选择指定主机或主机组 # 3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载) # 4. 充分 ...
- 类 Fabric 主机管理程序开发
类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载4. 充分使用多线程或多进程5. 不同主 ...
- paramiko类Fabric主机管理
环境:Linux python3.5 要求:类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/ ...
- python作业Select版本FTP(第十周)
SELECT版FTP: 使用SELECT或SELECTORS模块实现并发简单版FTP 允许多用户并发上传下载文件 思路解析: 1. 使用IO多路复用的知识使用SELECTORS封装好的SELECTOR ...
- 老男孩Day10作业:主机管理程序
一.作业需求: 1, 运行程序列出主机组或者主机列表 2,选择指定主机或主机组 3,选择主机或主机组传送文件(上传/下载) 4,充分使用多线程或多进程 5,不同主机的用户名,密码,端口可以不同 6,可 ...
- python作业模拟计算器开发(第五周)
作业需求: 模拟计算器开发: 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/1 ...
- python 作业
Linux day01 计算机硬件知识整理 作业要求:整理博客,内容如下 编程语言的作用及与操作系统和硬件的关系 应用程序->操作系统->硬件 cpu->内存->磁盘 cpu与 ...
随机推荐
- mac下面安装Navicat Premium 12.0.24 for mac已破解中文亲测可用
链接:https://pan.baidu.com/s/17HQ7dsCun2cSJGRpdP9yXA 密码:hwq5 Navicat_Premium_mac 最新版 12.0.24(原版是英文的) ...
- 第154天:canvas基础(一)
一.canvas简介 <canvas> 是 HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素.它可以用来制作照片集或者制作简单(也不是 ...
- caffe框架下目标检测——faster-rcnn实战篇操作
原有模型 1.下载fasrer-rcnn源代码并安装 git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git 1) ...
- jquery 集合注意点
- 洛谷 P1972 [SDOI2009]HH的项链
不是裸题,鉴定完毕. 我是题面 对于这道题,我是离线做的... 树状数组吧,好些点 我们可以很轻易地得到一个很显然的结论,就是关于同一个数,我们只需要记录它不超过当前区间的最后一次出现的位置即可.举例 ...
- C++解析(8):C++中的新成员
0.目录 1.动态内存分配 1.1 C++中的动态内存分配 1.2 new关键字与malloc函数的区别 1.3 new关键字的初始化 2.命名空间 2.1 作用域与命名空间 2.2 命名空间的定义和 ...
- 信息收集利器——Nmap
环境:kali2.0 常用的Nmap命令总结: 1.扫描单个IP地址 nmap 192.168.56.1 2.扫描一个网络中IP地址范围 nmap 192.168.56.1-255 3.扫描目标主机的 ...
- 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】
题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...
- C/C++ string.h头文件小结
http://note.youdao.com/noteshare?id=cff515f7b683f579d22f17b54b960e2a
- python函数的输入参数
http://note.youdao.com/noteshare?id=c2a0a39ee3cae09a62dcbc9f96d04b56