功能介绍
功能1:自动检测文件变动,并发送到另外一台计算机
两台windows计算机相互连接,计算机A监测本机指定文件夹下的文件变动,如果该文件夹中出现了新文件,则自动将其发送到计算机B的指定位置。
功能2:将python文件发送到另一台计算机并执行,并将执行结果传回本机
计算机B的性能要比计算机A的性能高很多,因此很多python代码要运行在计算机B,而A只起到收发python文件,并从计算机B那里获得运行结果的作用。
环境准备
开启win10 openssh服务
我们要把文件从计算机A发送到计算机B。
首先,在计算机B中进行操作。打开设置,搜索 管理可选功能
, 点击添加功能,下载安装openSSH服务器,还有OpenSSH客户端。安装完成后,在win10搜索框里搜索服务,设置这两个服务为自动启动:
安装所需要的库
在计算机A上安装一些python库:
scpclient:pip install scpclient
paramiko:pip install paramiko
pywinrm:pip install pywinrm
winrm的设置
winrm用于远程执行命令。
我们在计算机B上进行操作:
打开powersheell(管理员),输入命令: winrm quickconfig
,查看winrm是否开启成功,如果提示未开始,输入enter执行提示操作开始winrm。
接下来是把网络设置为 专用网络
,这个我发现surface pro4的 手机热点本身就被设置为了专用网络,就不再管了。
再接下来是执行两个命令(powershell 管理员模式):
winrm set winrm/config/service/auth @{Basic="true"}
然后就报出了这个错误:
经搜索发现,上面那条命令是错误的,真正正确的是: winrm set winrm/config/service/auth '@{Basic="true"}'
再接下来是按照【10】的说法,配置非加密服务: winrm set winrm/config/service '@{AllowUnencrypted="true"}'
代码编辑
然后在计算机A运行代码:
import paramiko
hostname="计算机B的ip地址"
port = 22
username = "计算机B开机时候的用户名"
password = "计算机B开机时候的密码"
transport = paramiko.Transport((hostname, port))
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
# 下载文件
sftp.get("D:/test.txt","D:/U盘/test.txt") # 把计算机B放在D->U盘里的test.txt放到计算机A的D盘根目录
# #上传文件
# sftp.put("./video.mp4","/home/share/video.mp4")
sftp.close()
以上就实现了两台计算机文件的发送。接下来是远程执行python脚本的代码:
import paramiko
import time
import os
import shutil
import winrm
import json
# hostname="10.201.147.111"
# username="dell"
# password="2019202210088"
hostname = "计算机B的ip地址"
username = "计算机B的用户名"
password = "计算机B的密码"
port = 22
transport = paramiko.Transport((hostname, port)) # 建立远程连接
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
class ServerByPara(object):
def __init__(self, cmd, host, user, password, system_choice):
self.cmd = cmd
self.client = paramiko.SSHClient()
self.host = host
self.user = user
self.pwd = password
self.system_choice = system_choice
def exec_linux_cmd(self):
data_init = ''
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(hostname=self.host, username=self.user, password=self.pwd)
stdin, stdout, stderr = self.client.exec_command(self.cmd, get_pty=True)
if stderr.readlines():
exec_tag = 1
for data in stdout.readlines():
data_init += data
else:
exec_tag = 0
for data in stdout.readlines():
data_init += data
return json.dumps({
"exec_tag": exec_tag,
"data": data_init,
}, ensure_ascii=False)
def exec_win_cmd(self):
data_init = ""
s = winrm.Session(self.host, auth=(self.user, self.pwd))
ret = s.run_cmd(self.cmd)
if ret.std_err.decode():
exec_tag = 1
for data in ret.std_err.decode().split("rn"):
data_init += data
else:
exec_tag = 0
for data in ret.std_out.decode().split("rn"):
data_init += data
return json.dumps({
"exec_tag": exec_tag,
"data": data_init,
}, ensure_ascii=False)
def run(self):
if self.system_choice == "Linux":
result = self.exec_linux_cmd()
else:
result = self.exec_win_cmd()
print(result)
with open(r"script_info.txt", "w") as f:
f.write(result)
def sendFile(hereFilePath,thereFilePath):
# 上传文件
print(hereFilePath)
print(thereFilePath)
sftp.put(hereFilePath, thereFilePath)
# 首先检查指定文件夹是否有文件
while True:
fileList=os.listdir("D:codes")
if len(fileList)>0: # 如果有文件就把所有文件都上传到计算服务器
print("存在文件")
for file in fileList:
folder=file.split(".")[0]
originFilePath=os.path.join("D:/codes",file)
filePath=os.path.join("D:/codes/"+folder,file)
sendFile(originFilePath,"D:/"+file)
shutil.move(originFilePath,"D:/backup/"+file)
# 运行解压程序
print("运行解压程序")
print("python D:/unzip.py "+"D:/"+file+" D:/codes/")
server_obj = ServerByPara("python D:/unzip.py "+"D:/"+file+" D:/codes/", hostname, username, password, "windows")
server_obj.run()
time.sleep(3)
# 上传完成后执行命令
pyFile=filePath.replace(".zip",".py")
print("开始运行:",pyFile)
server_obj = ServerByPara("python "+pyFile, hostname, username, password, "windows")
server_obj.run()
print("运行结束")
else:
print("未扫描到文件")
time.sleep(10)