Python 进行 SSH 操作,实现本地与服务器的链接,进行文件的上传和下载


2018年5月26日 19:03 阅读 375 评论 7

我本地和服务器的连接一直使用的是 Xshell 5,而在与服务器进行文件操作的时候使用的是 Xshell 推荐安装的一个工具 Xftp 5,然而,昨天自己想着从服务器下载备份好的的数据库文件到本地的时候发现这个文件传输工具居然过期不能用了,好气啊!于是没办法(机智如我)只好用 Python 来实现 SSH 的连接,顺便从服务器批量下载一些文件,实现自动化。

项目介绍

SSH 使用的库

首先需要介绍一个 Python 实现 SSH 连接的第三方库,名字叫做 paramiko,经过一个短暂的熟悉,我发现这个库基本可以实现 SSH 连接中的一些常用方法,具体使用可以去看一些教程或者官方文档。

我还是比较喜欢从实际的应用出发来加深对一些新接触的第三方库的认知,所以有了这篇文章中涉及到的实际应用案例。

脚本思路

首先来介绍一下我这个简单的自动化脚本做的事情(由于想实现的事情比较单一且固定,所以直接写成了几个函数,写的比较随意):

  1. 首先创建一个配置文件,用来存放登录服务器的一些参数,例如服务器 host,端口 port,用户名称和密码等。
  2. 读取配置文件的信息,返回一个字典以备后续调用
  3. 使用 SSH 链接服务器,并且执行几个 shell 命令,返回需要下载的文件的绝对地址列表
  4. 连接 SFTP 批量下载文件到本地

源码解读

源码展示

# -*- coding: utf-8 -*-
import paramiko
import os
from configparser import ConfigParser # 读取配置文件获取服务器的登录信息
def read_ini():
info = dict()
cf = ConfigParser()
cf.read('config.ini', encoding='utf-8')
keys = cf.options('ssh')
for each in keys:
info[each] = cf.get('ssh', each)
print(info)
return info # 连接服务区并执行shell命令返回输出结果
def ssh_test(host, port, username, password):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
try:
ssh.connect(hostname=host, port=port, username=username, password=password)
except Exception as e:
print(e)
return # 设置一个内部函数,执行shell命令并返回输出结果
def run_shell(cmd):
ssh_in, ssh_out, ssh_error = ssh.exec_command(cmd)
result = ssh_out.read() or ssh_error.read()
return result.decode().strip() # 获取指定文件夹的绝对地址
cmd_get_path = 'cd dbs;pwd'
db_path = run_shell(cmd_get_path) # 获取指定文件夹中文件的名称,并跟上面得到的文件夹绝对地址组合起来
cmd_get_sqls = 'cd dbs;ls'
sqls = run_shell(cmd_get_sqls)
lis = ['{}/{}'.format(db_path, each) for each in sqls.split('\n')]
print(lis) # 关闭连接
ssh.close()
return lis # 链接服务器进行文件传输
def sftp_test(host, port, username, password, from_file, to_file):
transport = paramiko.Transport((host, port))
try:
transport.connect(username=username, password=password)
except Exception as e:
print(e)
return
sftp = paramiko.SFTPClient.from_transport(transport) # 将文件下载到本地,如果是上传使用 put
sftp.get(from_file, to_file)
transport.close() if __name__ == '__main__':
info = read_ini()
h = info.get('host', None)
p = int(info.get('port', None)) # 端口是int类型
u = info.get('username', None)
pw = info.get('password', None)
files = ssh_test(h, p, u, pw) path = 'F:\\dbs'
if files:
for each in files:
name = each.split('/')[-1]
ss = sftp_test(h, p, u, pw, each, os.path.join(path, name))

配置文件读取

首先,配置文件是放在跟脚本同目录下的,文件名称为 config.ini,配置的信息格式遵循一般的配置文件的格式,如下:

[ssh]
host=119.23.106.34
port=22
username=user
password=password

只需要提供以上四个信息就可以连接到服务器。

读取配置信息的方式是函数 read_ini(),这个函数使用 Python 内置的库 configparser 去读取配置文件,并且返回一个键值对的字典,以供后续的函数调用。

def read_ini():
info = dict()
cf = ConfigParser()
cf.read('config.ini', encoding='utf-8')
keys = cf.options('ssh')
for each in keys:
info[each] = cf.get('ssh', each)
print(info)
return info

SSH 连接执行

ssh_test 函数是用来连接 SSH 的方法,这个方法接受4个参数,也就是上面的配置文件需要提供的参数。

首先需要创建一个 ssh 连接的实例:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

然后传入相关参数,尝试连接到远程服务器:

try:
ssh.connect(hostname=host, port=port, username=username, password=password)
except Exception as e:
print(e)
return

当服务器已经连接成功之后,可以进行 shell 命令的操作了,我把这个执行 shell 命令的操作过程写到一个内嵌的函数中,这样可以方便执行不同的命令:

def run_shell(cmd):
ssh_in, ssh_out, ssh_error = ssh.exec_command(cmd)
result = ssh_out.read() or ssh_error.read()
return result.decode().strip()

ssh.exec_command(cmd) 会得到三个对象,其中第二个就是命令执行成功的结果,第三个是命令执行失败的结果,所以我们可以取第二个的结果作为命令执行成功返回的结果,结果需要转码,并且要去掉末尾的换行符。

这里我首先执行了一条 shell 命令,多个命令直接需要使用分号隔开,这个命令是返回当前文件夹的绝对地址:

cmd_get_path = 'cd dbs;pwd'

命令执行的结果放到一个变量中保存,后续需要调用:

db_path = run_shell(cmd_get_path)

然后第二条 shell 命令是返回指定文件夹下的所有文件,我这里是返回的自己的服务器上面数据库备份的文件,通过看代码就能看到我这里处理了一下文件名称,让它们变成了绝对地址,这样方便后续下载文件。

最后这个函数返回的就是一个服务器上面的文件夹中包含的所有文件的绝对地址组成的列表。

SFTP 下载文件

下载文件的操作写在函数 sftp_test() 中,这个函数除了要传递登录服务器的4个基本参数外,还要传递2个参数,第一个是服务器上面的文件的绝对地址,第二个是本地保存的文件的地址(相对地址和绝对地址都行)。

看代码,这里和连接 SSH 有一些区别,不过大体的思路一样,都是先创建实例,然后尝试连接:

transport = paramiko.Transport((host, port))
try:
transport.connect(username=username, password=password)
except Exception as e:
print(e)
return
sftp = paramiko.SFTPClient.from_transport(transport)

连接之后,就可以使用 get() 方法来下载文件了,如果要上传的话,可以使用与之对应的 put() 方法:

sftp.get(from_file, to_file)

执行代码

最后执行代码的过程其实就是之前讲到的项目思路,首先运行配置文件读取的函数,读取配置:

info = read_ini()
h = info.get('host', None)
p = int(info.get('port', None)) # 端口是int类型
u = info.get('username', None)
pw = info.get('password', None)

这里需要注意,由于端口接受的是一个 int 类型,而在配置中是字符串,所有需要转换一下才能使用,不然就会报错。

读取了配置就可以连接 SSH 然后返回文件的绝对地址:

files = ssh_test(h, p, u, pw)

最后使用循环来分别下载每个文件到本地保存即可:

path = 'F:\\dbs'
if files:
for each in files:
name = each.split('/')[-1]
ss = sftp_test(h, p, u, pw, each, os.path.join(path, name))

总结:使用 Python 连接服务器进行操作在运维自动化中应该使用会比较多,这篇文章主要是通过一个实例来介绍一下 Python 连接 SSH 之后的基本操作,还有更多的操作有待读者自己去学习和实战。

原创文章,转载请注明出处:http://www.tendcode.com/article/python-ssh/

Python 进行 SSH 操作,实现本地与服务器的链接,进行文件的上传和下载的更多相关文章

  1. C# 本地文件的上传和下载

    本文主要介绍一下,在APS.NET中文件的简单上传于下载,上传是将文件上传到服务器的指定目录下,下载是从存入数据库中的路径,从服务器上下载. 1.上传文件 (1)页面代码 <table alig ...

  2. Python实现FTP文件的上传和下载

    # coding: utf-8 import os from ftplib import FTP def ftp_connect(host, username, password): ftp = FT ...

  3. 『心善渊』Selenium3.0基础 — 19、使用Selenium操作文件的上传和下载

    目录 1.Selenium实现文件上传 (1)页面中的文件上传说明 (2)文件上传示例 (3)总结 2.Selenium实现文件下载 (1)Firefox浏览器文件下载 1)操作步骤: 2)文件下载示 ...

  4. [java] java 实现FTP服务器文件的上传和下载

    利用Apache commons-net 实现: package com.xwolf.driver.util; import com.xwolf.driver.exception.RunExcepti ...

  5. 【Struts】服务器文件的上传和下载

    Java中获得文件的文件后缀 import java.io.*; public class FileTest{ public static void main(String args[]){ File ...

  6. python 解决粘包问题的例子(ftp文件的上传与下载)简单版本

    服务端 ! /user/bin/env python3 -- coding:utf_8 -- """ Author:Markli # 2019/9/9,16:41 &qu ...

  7. Linux本机和远程服务器之间文件的上传和下载 rz sz

    tar zxvf lrzsz-0.12.20.tar.gz 解压安装包   下载地址:链接:https://pan.baidu.com/s/1KMS1QlyOhpXiYeaWdNBAyw 提取码:08 ...

  8. Python——操作smb文件服务器(上传和下载)

    最近在做上传和下载,然后文件比较大和多,就用到了文件服务器,文件服务器是实体机 ,不是在本地, 然后用python 通过pysmb模块就可以直接进行操作 mac选择前往.连接服务器去查看文件服务器里都 ...

  9. Python + Selenium + AutoIt 模拟键盘实现另存为、上传、下载操作详解

    前言 在web页面中,可以使用selenium的定位方式来识别元素,从而来实现页面中的自动化,但对于页面中弹出的文件选择框,selenium就实现不了了,所以就需引用AutoIt工具来实现. Auto ...

随机推荐

  1. Java基础2-容器篇

    java基础2-容器篇 1.页首请关注 思维导航大纲 1.常用容器的类型层次结构 2.理解容器的常用思维大纲 a.空间 时间 concurrentModifyException 加载因子 3.常用类源 ...

  2. 搭建Go调试环境(LiteIDE)

                安装及配置LiteIDE 将 liteidex32.1.windows-qt5.zip解压到D:\即完成安装.   设置编辑环境 查看->编辑当前环境,确认GOROOT变 ...

  3. socket概述和字节序、地址转换函数

    一.什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口. socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信. socket API是一层抽象的网 ...

  4. GDI+绘制简单图形

    #include <windows.h>#include <gdiplus.h>using namespace Gdiplus;#pragma comment(lib, &qu ...

  5. 页面日期选择控件--jquery ui datepicker 插件

    日期选择插件Datepicker是一个配置灵活的插件,我们可以自定义其展示方式,包括日期格式.语言.限制选择日期范围.添加相关按钮以及其它导航等.官方地址:http://docs.jquery.com ...

  6. python标准库介绍——18 StringIO 模块详解

    ==StringIO 模块== [Example 2-8 #eg-2-8] 展示了 ``StringIO`` 模块的使用. 它实现了一个工作在内存的文件对象 (内存文件). 在大多需要标准文件对象的地 ...

  7. 如何判断SCI期刊投稿难易度和审稿周期

    如何判断SCI期刊投稿难易度和审稿周期 要发SCI论文,前提当然是必须有一篇写好的英文论文,SCI都是英文的杂志,这个大家应该都懂的     首先谈谈投稿难易程度很多人似乎都一种误解,认为拒稿率高的杂 ...

  8. laravel中间件简单使用

    laravel内置了一个中间件来验证用户是否经过认证,如果用户没有经过认证,中间件会将用户重定向到登录页面,否则如果用户经过认证,中间件就会允许请求继续往前进入下一步操作. 当然,除了认证之外,中间件 ...

  9. 深入理解Docker Volume(二)

      一开始,认为Volume是用来持久化的,但是这实际上不对,因为认为Volume是用来持久化的同学一定是认为容器无法持久化,所以有了Volume来帮助容器持久化,事实上,容器会一直存在,除非你删除他 ...

  10. malefile

    什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要 ...