目录

简介-paramiko

安装paramiko 

 使用paramiko进行SSH连接

使用paramiko进行文件传输

与shell交互使用

 补充

FTP传输文件


简介-paramiko

Python中实现远程连接需要用到外部模块,主要有paramikopexpect等。

paramiko主要执行远程连接和文件传输(即SSHClientSFTPClinet),非Python自带,需要手动安装。

安装paramiko 

pip install --upgrade pip #更新pip版本
pip install paramiko      #安装

 使用paramiko进行SSH连接

def SshSingle():
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 设置白名单
    ssh.connect(hostname='192.168.222.128, username='root', password='123456', port='22')
    stdin, stdout, stderr = ssh.exec_command("ls -l /root")
    # 标准格式输入、输出、错误
    res, err = stdout.read(), stderr.read()
    result = res if res else err
    print(result.decode())
    # 输出结果
    ssh.close()

set_missing_host_policy方法是将SSH连接的KEY保存到know_hosts中,采用AutoAddPolicy()是自动为你保存的意思不需要手动输入yes来建立信任。具体使用及其他方法使用规则请参考官方文档。

https://www.paramiko.org/

多线程进行SSH连接见后下文

使用paramiko进行文件传输

def DloadUpload():
    sftp = paramiko.Transport(sock=('192.168.222.128', 22))
    sftp.connect(username='root', password='123456')
    files = paramiko.SFTPClient.from_transport(sftp)
    # 
    try:
        # Download
        # files.get("~/test.tx", "C:/Users/boy/Desktop/new.txt")
        # get中前面为远程服务器文件路径及文件名,后面为下载到本地的路径及文件名
        # 用例中本地平台为Windows
        # Upload
        files.put("C:/Users/boy/Desktop/shell.txt", "/root/shell")
        # put中前面为本地文件路径及文件名,后面为上传到远程服务器的路径及文件名
        # filelist = files.listdir("/root/")
        # for f in filelist:
        #     files.get(os.path.join("/root/", f), os.path.join("C:/Users/boy/Desktop/", f)
    except Exception as result:
        print(result)
    sftp.close()

SFTPClient类其他方法介绍:

listdir,获取远程SFTP服务端指定目录列表,如批量下载一个目录下的所有文件,上述代码注释部分;

mkdir,在SFTP服务端创建目录;

remove,删除SFTP服务端指定目录;

stat,获取远程SFTP服务端指定文件信息

与shell交互使用

def SshShell():
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname='192.168.222.128', username='root', password='123456', port='22')
    shell = ssh.invoke_shell()
    shell.settimeout(1)
    # cmd = input()
    # shell.send(cmd + '\r')
    while True:
        time.sleep(0.5)
        # 设置睡眠时间以打印返回结果
        recv = shell.recv(10240).decode()
        if recv:
            print(recv)
        cmd = input()
        if cmd == 'quit':  #当输入quit时退出交互
            break
        else:
            shell.send(cmd + '\n')
    ssh.close()

 补充

利用多线程进行SSH连接

pool = [dict(host='192.168.222.128', username='root', password='123456', port='22'),
        dict(host='192.168.222.129', username='root', password='123456', port='22'),
        dict(host='192.168.222.130', username='root', password='123456', port='22')
        ]
# 定义一个IP池
class SshThreading(threading.Thread):
# 封装
    def __init__(self, cmd, host, username, password, port):
        self.cmd = cmd
        self.host = host
        self.username = username
        self.password = password
        self.port = port
        super(SshThreading, self).__init__()

    def run(self):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname=self.host, username=self.username, password=self.password, port=self.port)
        stdin, stdout, stderr = ssh.exec_command(self.cmd)
        res, err = stdout.read(), stderr.read()
        result = res if res else err
        print("[ip:%s] \n%s" % (self.host, self.cmd))
        print(result.decode())
        ssh.close()


def SshMUti():
    cmd = "ls -l /root"
    thread_pool = []
    for host in pool:
        t = SshThreading(host=host.get("host"),
                         username=host.get("username"),
                         password=host.get("password"),
                         port=host.get("port"),
                         cmd=cmd
                         )
        # print(host.get("password"))
        thread_pool.append(t)
    for t in thread_pool:
        t.start()

FTP传输文件

与FTP服务器进行文件传输,需要ftplib

from ftplib import FTP


def FtpDownFile(allfile):
    a = []
    for f in allfile:
        a.append(f)
    # 可以先判断a是否不为空
    for i in range(len(a)):
        file_handler = open('C:/Users/boy/Desktop/' + a[i], 'wb').write
        # 确保写入目录用户具有写权限
        ftp.retrbinary('RETR %s' % a[i], file_handler)


def FtpUpFile():
    file = open('C:/Users/boy/Desktop/123.txt', 'rb')
    ftp.storbinary('STOR %s' % '123.txt', file)
    file.close()


if __name__ == '__main__':
    ftp = FTP()
    ftp.encoding = 'utf-8'
    ftp.connect(host='192.168.222.128', port=21)
    ftp.login("root", "123456")
    print(ftp.welcome)
    print('\n')
    ftp.cwd("/var/ftp/pub/")
    all_file = ftp.nlst()
    # FtpDownFile(all_file) #下载
    FtpUpFile()             #上传
    ftp.close()
    exit()