python paramiko 多线程批量执行指令及批量上传文件和目录

源代码:

https://github.com/jy1779/be.git

环境需求:

1、python3

2、paramiko

pip install --upgrade pip

apt-get install libssl-dev

pip3 install paramiko

3、执行权限

chmod +x becmd.py

ln -s /root/be/bin/becmd.py /usr/local/sbin/becmd

chmod +x besync.py

ln -s /root/be/bin/becmd.py /usr/local/sbin/besync

4、导入路径设置

cd /usr/lib/python3.5/dist-packages/

touch be.pth

vim be.pth

/root/be     #be.pth文件内容

5、因为是从windows开发所以会出现以下问题:

windows 上传的文件,可以用这个指令格式化成Unix文件。

apt install dos2unix

[email protected]:~/be/bin# ./besync.py

/usr/bin/env: ‘python3\r’: No such file or directory

[email protected]:~/be/bin# dos2unix besync.py

dos2unix: converting file besync.py to Unix format ...

[email protected]:~/be/bin# ./besync.py

Reminder: The source and destination addresses do not exist

Usage: ./besync.py <source address> <destination address>

解决

apt install dos2unix

dos2unix becmd.py

dos2unix besync.py

6、日志路径的问题。最好是绝对路径,不然只能在be目录下执行becmd 和besync

f = open("/root/be/logs/besync.log",‘a‘)

f = open("/root/be/logs/becmd.log",‘a‘)

程序目录:

.
├── app
│   ├── __init__.py
│   ├── pwd_connect_cmd.py
│   ├── pwd_connect_sync.py
│   ├── __pycache__
│   │   ├── __init__.cpython-35.pyc
│   │   ├── pwd_connect_cmd.cpython-35.pyc
│   │   ├── pwd_connect_sync.cpython-35.pyc
│   │   ├── ssh_be_cmd.cpython-35.pyc
│   │   └── ssh_be_sync.cpython-35.pyc
│   ├── ssh_be_cmd.py 
│   └── ssh_be_sync.py
├── bin
│   ├── becmd.py
│   ├── besync.py
│   └── __init__.py
├── conf
│   ├── config.py
│   ├── __init__.py
│   └── __pycache__
│       ├── config.cpython-35.pyc
│       └── __init__.cpython-35.pyc
├── __init__.py
└── logs
    ├── becmd.log
    ├── besync.log
    └── __init__.py

app/ssh_be_cmd.py

import paramiko
import threading
import datetime
class MyThread(threading.Thread):
    def __init__(self,ip,port,username,password,cmd):
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        super(MyThread,self).__init__()
        self.ip = ip
        self.port = port
        self.username = username
        self.password = password
        self.cmd = cmd
    def run(self):
        port = int(self.port)
        self.ssh.connect(hostname=self.ip, port=port, username=self.username, password=self.password)
        stdin, stdout, stderr = self.ssh.exec_command(self.cmd)
        res, err = stdout.read(), stderr.read()
        result = res if res else err
        f = open("/root/be/logs/becmd.log",‘a‘)
        f.write(str(datetime.datetime.now())+" ")
        f.write(self.ip+" ")
        f.write(self.username+ " ")
        f.write(self.cmd+ "\n")
        f.close()
        print("\033[1;32;40m" + self.ip.rjust(33,‘=‘)+ "\033[0m","\033[1;32;40m" + "Command result: ".ljust(37,‘=‘)+ "\033[0m")
        print(result.decode())
        self.ssh.close()

app/pwd_connect_cmd.py

import sys
from app.ssh_be_cmd import MyThread
from conf.config import account
def pwd_con(host):
    ip = account[host]["ip"]
    port = account[host]["port"]
    username = account[host]["username"]
    password = account[host]["password"]
    a=sys.argv[1:100]
    cmd = " ".join(a)
    if len(a) >=1:
        M = MyThread(ip,port,username,password,cmd)
        M.start()
    else:
        print("Reminder: The command does not exist")
        exit()
def connect():
    for host in account.keys():
        pwd_con(host)

app/ssh_be_sync.py

import paramiko
import threading
import datetime,time
import os
from os.path import getsize
class MyThread(threading.Thread):
    def __init__(self,ip,port,username,password,cmd):
        super(MyThread,self).__init__()
        self.ip = ip
        self.port = port
        self.username = username
        self.password = password
        self.cmd = cmd
    def run(self):
        port = int(self.port)
        self.transport = paramiko.Transport((self.ip, port))
        self.transport.connect(username=self.username, password=self.password)
        self.sftp = paramiko.SFTPClient.from_transport(self.transport)
        help="""
                -f send file to remote host.
                   %s -f <source address> <destination address>
                -d send dir to remote host.
                   %s -d <source address> <destination address>
                --help show help.
                   %s --help
            """%(self.cmd[0],self.cmd[0],self.cmd[0])
        def create_remote_dir(dir):
            for item in dir:
                try:
                    self.sftp.stat(item)
                    pass
                except FileNotFoundError:
                    print("Create a new directory: ", item)
                    self.sftp.mkdir(item)
        def besync_log():
            f = open("/root/be/logs/besync.log",‘a‘)
            for i in str(datetime.datetime.now())+" ",self.ip+" ",self.username+ " ",self.cmd[0]+" ",self.cmd[1]+" ",src+" ",des+ "\n":
                f.write(i)
            f.close()
        if len(self.cmd) == 4 and self.cmd[1] == "-f":
            src = self.cmd[2]
            des = self.cmd[3]
            besync_log()
            time_start = time.time()
            if os.path.isfile(src):
                des_list = des.split("/")
                des_dir = des_list[1:-1]
                b=""
                c=[]
                for item in des_dir:
                    b+="/"+item
                    c.append(b)
                create_remote_dir(c)
                self.sftp.put(src, des)
                total_time = time.time() - time_start
                print("\033[1;32;40mSend Successful.\033[0m")
                print("total size: " + str(getsize(src)) + " bytes")
                print("total time: " + str(total_time))
                self.transport.close()
        elif len(self.cmd) == 4 and self.cmd[1] == "-d":
            def for_dir():
                for res in path:
                    if os.path.isdir(res):
                        local_dir_path.append(res)
                remote_dir_path.append(des)
            def for_zdir():
                des_src_dir.append(remote_dir_path[1])
                des_src_dir_list = des_src_dir[0].split("/")
                des_dir_list = des_src_dir_list[1:]
                c = ""
                remote_des_src_path = []
                for item in des_dir_list:
                    c += "/" + item
                    remote_des_src_path.append(c)
                create_remote_dir(remote_des_src_path)
                create_remote_dir(remote_dir_path)
                for res in path:
                    if os.path.isfile(res):
                        local_file_path.append(res)
            src = self.cmd[2]
            des = self.cmd[3]
            besync_log()
            sep = "/"
            path = []
            local_dir_path = []
            local_file_path = []
            remote_dir_path = []
            remote_file_path = []
            des_src_dir = []
            for i in os.listdir(src):
                path.append(src + sep + i)
            for n in path:
                if os.path.isdir(n) and os.listdir(n):
                    for i in os.listdir(n):
                        path.append(n + sep + i)
            local_dir_path.append(src)
            local_dir = src.split("/")
            local_dir_first = local_dir[0:-1]
            global a
            if len(local_dir_first) == 0:
                for_dir()
                for res in local_dir_path:
                    remote_dir_path.append(des + "/" + res)
                for_zdir()
                for res in local_file_path:
                        remote_file_path.append(des + "/" + res)
            else:
                if len(local_dir_first) ==1:
                    dir_join="/".join(local_dir_first)
                    a=dir_join
                else:
                    dir_join="/".join(local_dir_first)
                    a=dir_join+"/"
                for res in path:
                    if os.path.isdir(res):
                        local_dir_path.append(res)
                remote_dir_path.append(des)
                b=[item.split(a)[-1] for item in local_dir_path]
                for res in b:
                    if len(local_dir_first) ==1:
                        remote_dir_path.append(des + res)
                    else:
                        remote_dir_path.append(des + "/" + res)
                for_zdir()
                d = [item.split(a)[-1] for item in local_file_path]
                for res in d:
                    if len(local_dir_first) ==1:
                        remote_file_path.append(des + res)
                    else:
                        remote_file_path.append(des + "/" + res)
            time_start = time.time()
            local_file_num = len(local_file_path)
            for i in range(local_file_num):
                self.sftp.put(local_file_path[i],remote_file_path[i])
            total_time = time.time() - time_start
            print("\033[1;32;40mSend Successful.\033[0m")
            print("total time: " + str(total_time))
            self.transport.close()
        else:
            print(help)

app/pwd_connect_sync.py

import sys
from app.ssh_be_sync import MyThread
from conf.config import  account
def pwd_con(host):
    ip = account[host]["ip"]
    port = account[host]["port"]
    username = account[host]["username"]
    password = account[host]["password"]
    cmd=sys.argv[0:100]
    M = MyThread(ip, port, username, password, cmd)
    M.start()
def connect():
    for host in account.keys():
        pwd_con(host)

conf/config.py

account = {
    "192.168.1.57":{
        "ip":"192.168.1.57",
        "port":"22",
        "username":"root",
        "password":"123456"
    },
     "192.168.1.75":{
         "ip": "192.168.1.75",
         "port": "22",
         "username": "root",
         "password": "123456"
     }
}

bin/becmd.py

#!/usr/bin/env python3
from app.pwd_connect_cmd import connect
connect()

bin/besync.py

#!/usr/bin/env python3
from app.pwd_connect_sync import connect
connect()

使用例子:

1、批量执行指令:

2、批量上传文件

3、批量上传目录

时间: 2024-10-11 04:22:52

python paramiko 多线程批量执行指令及批量上传文件和目录的相关文章

利用paramiko模块批量登录(执行命令/上传文件)

工作中由于服务器主机很多,如果手动的一台一台去添加ssh认证,效率太低了,而此脚本正是为了解决此问题 此脚本的实现的功能: 1.实现了(密码.ssh认证)单一主机登录和批量主机登录 2.实现了(密码.ssh认证)单一主机上传文件和批量主机上传文件(下载文件的原理和此一样) 3.主机批量添加ssh认证(这才是我的主要目的) 脚本的不足: 1.只能循环主机名 2.所有的主机的账号和密码都是一样的,不够灵活 有需求的朋友可以修改下代码,可以把主机.账号密码存放在一个文件中,循环读取文件 下面贴上代码吧

使用python或robotframework调multipart/form-data接口上传文件

这几天调一个multipart/form-data类型的接口,遇到点小阻碍.之前同事有使用urllib库写了个类似的方法实现,比较长,想要改的时候发现不太好使.在网上查找发现用requests库做这个更强大.下面具体介绍一下python-requests及robotframework-RequestsLibrary实现multipart/form-data接口上传文件.1.从fiddler查看接口长这样:Header: WebForms: 2.python-requests实现 #!/usr/b

《selenium2 python 自动化测试实战》(13)——上传文件

看代码: # coding: utf-8 from selenium import webdriver from time import sleep driver = webdriver.Firefox() driver.get("https://www.cnblogs.com") driver.add_cookie({'name': '.CNBlogsCookie', 'value': 'F956F323DFA5C31BE489C0730C7D891', 'domain': '.cn

javaweb:11.上传文件之目录打散

public class Upload3Servlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;

Linux下开发python django程序(设置admin后台管理上传文件)

1.项目创建相关工作参考前面 2.在models.py文件中定义数据库结构 import django.db import modelsclass RegisterUser(models.Model): username=models.CharField(max_length=30) headImg = models.FileField(upload_to='./upload/') def __unicode__(self): return self.username 3.生成数据库 pytho

selenium 上传文件方法补充——SendKeys、win32gui

之前和大家说了input标签的上传文件的方式: <selenium2 python 自动化测试实战>(13)--上传文件 现在好多网站上传的标签并不是input,而是div之类的比如: 全部都是div标签,这时候用上面的方法就不好用了.今天船长在大神的帮助下学会了两种方法,现在船长来教大家上传div这种标签的方式. 最方便的--SendKeys 大家只需要pip install SendKeys库,然后再代码里直接用就OK了,这里用大鱼号上传视频作为例子上代码: 注意,浏览器用的是火狐,因为c

Java 网络编程案例三:多个客户端上传文件

需求:每一个客户端启动后都可以给服务器上传一个文件,服务器接收到文件后保存到一个upload目录中.可以同时接收多个客户端的文件上传. 分析: (1)服务器端要“同时”处理多个客户端的请求,那么必须使用多线程,每一个客户端的通信需要单独的线程来处理. (2)服务器保存上传文件的目录只有一个upload,而每个客户端给服务器发送的文件可能重名,所以需要保证文件名的唯一.我们可以使用“时间戳”作为文件名,而后缀名不变 (3)客户端需要给服务器上传文件名(含后缀名)以及文件内容.而文件名是字符串,文件

android 上传文件到服务器

Android客户端 package com.example.testandroid;   import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL;   import android.app.Activity; import android.app.Alert

前端js上传文件 到后端接收文件

下面是前端js代码: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> <!-- // action="fileupload"对应web.xml中<se