paramiko库基本用法——建立SSH连接、远程执行命令和上传下载文件

本文讲述的核心库:paramiko
官方文档:http://docs.paramiko.org/en/2.4/

准备工作:paramiko库安装、测试环境搭建

paramiko库安装

pip install paramiko

测试环境搭建

测试和远程服务器的交互,那首先得有一台远程主机,可以在阿里云申请虚拟机,但是成本有点高。如果想要便捷一点,其实可以在自己电脑上用Vmware搭建一个Linux虚拟机充当远程主机,搭建方法可以参考:VMware Workstation + Lubuntu打造极速虚拟机环境

建立和远程服务器的SSH连接

在远程服务器上执行各种操作的前提是首先建立和远程服务器的连接,这里使用SSH连接:

# coding:utf-8
import paramiko

def login(ip,username,password,port = 22):
    '''
    用paramiko SSH登录远程服务器
    
    :param ip: 远程服务器的IP
    :param username: 远程服务器登录用户名
    :param password: 远程服务器登录用户密码
    :param port: 远程服务器的端口,SSH协议默认为22
    '''
    # 创建一个SSH客户端对象
    ssh = paramiko.SSHClient()
    # 设置访问策略
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 与远程主机进行连接
    ssh.connect(hostname = ip,port = port,username = username,password = password)
    return ssh

def main():
    ip = '192.168.xxx.xxx'
    username = '***'
    password = '***'
    ssh = login(ip,username,password)
    print type(ssh)
    
if __name__ == '__main__':
    main()

执行上述代码,输出:

<class 'paramiko.SSHClient'>

可见,当和远程服务器建立的SSH连接成功后,会创建出一个SSHClient对象。

在远程服务器上执行命令

# coding:utf-8
import paramiko

def execute_command(ssh,command_str):
    '''
    执行远程命令
    
    :param ssh: SSH连接对象
    :param command_str: 命令字符串
    '''
    input,output,err = ssh.exec_command(command_str)
    resp,error = output.read(),err.read()
    # 这里对命令执行结果和异常的处理方式还有待思考
    if resp:
        return resp
    print 'error occurs: {0}'.format(error)
    raise Exception(error)

def main():
    ip = '192.168.xxx.xxx'
    username = '***'
    password = '***'
    ssh = login(ip,username,password)
    
    command = 'ls /home/m2fox'
    print execute_command(ssh,command)
    
if __name__ == '__main__':
    main()

执行上面代码,输出:

Desktop
Documents
Downloads
Music
Pictures
Public
Templates
tmp
Videos

这是在我的虚拟机上/home/m2fox目录下的文件和文件夹列表。

上传、下载文件

  • 首先在当前目录创建一个hello.txt文件,其文件内容如下:
hello, paramiko!
  • 上传、下载代码:
# coding:utf-8
import paramiko

def upload_file(ssh,local_file_path,remote_file_path):
    '''
    上传文件
    
    :param ssh: SSH连接对象
    :param local_file_path: 本地文件路径
    :param remote_file_path: 远程文件存放路径
    '''
    # 创建sftp对象上传文件
    sftp = ssh.open_sftp()
    sftp.put(local_file_path,remote_file_path)
    sftp.close()
    
def download_file(ssh,remote_file_path,local_file_path):
    '''
    下载文件
    
    :param ssh: SSH连接对象
    :param remote_file_path: 远程文件路径
    :param local_file_path: 本地文件存放路径
    '''
    # 创建sftp对象下载文件
    sftp = ssh.open_sftp()
    sftp.get(remote_file_path,local_file_path)
    sftp.close()

def main():
    ip = '192.168.xxx.xxx'
    username = '***'
    password = '***'
    ssh = login(ip,username,password)
    
    # 上传文件
    upload_file(ssh,'./hello.txt','/home/m2fox/hello.txt')
    # 下载文件
    download_file(ssh,'/home/m2fox/hello.txt','e:/hello.txt')
    
if __name__ == '__main__':
    main()

执行上述代码,然后到虚拟机的/home/m2fox/目录查看:

发现hello.txt文件以已经被成功上传到/home/m2fox/目录,文件内容也是正确的。

再打开本地E盘根目录,发现从虚拟机下载hello.txt成功:

SSHUtil封装

将上面讲到的几项基本功能封装成一个类:SSHUtil,便于以后使用。

# coding:utf-8
# 封装常用的SSH功能
import paramiko

class SSHUtil(object):
    '''
    封装常用的SSH功能,包括:
    * 远程登录
    * 远程执行命令
    * 上传文件
    * 下载文件
    '''
    def __init__(self,ip,username,password,port = 22):
        '''
        初始化
        
        :param ip: 远程服务器的IP
        :param username: 远程服务器登录用户名
        :param password: 远程服务器登录用户密码
        :param port: 远程服务器的端口,SSH协议默认为22
        '''
        self.ip = ip
        self.port = port
        self.username = username
        self.password = password
        # 登录,获取SSH对象
        self.login(ip,username,password,port)
    
    def login(self,ip,username,password,port = 22):
        '''
        用paramiko SSH登录远程服务器
        
        :param ip: 远程服务器的IP
        :param username: 远程服务器登录用户名
        :param password: 远程服务器登录用户密码
        :param port: 远程服务器的端口,SSH协议默认为22
        '''
        # 创建一个SSH客户端对象
        self.ssh = paramiko.SSHClient()
        # 设置访问策略
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 与远程主机进行连接
        self.ssh.connect(hostname = ip,port = port,username = username,password = password)

    def execute_command(self,command_str):
        '''
        执行远程命令
        
        :param ssh: SSH连接对象
        :param command_str: 命令字符串
        '''
        input,output,err = self.ssh.exec_command(command_str)
        resp,error = output.read(),err.read()
        if resp:
            return resp
        print 'error occurs: {0}'.format(error)
        raise Exception(error)

    def upload_file(self,local_file_path,remote_file_path):
        '''
        上传文件
        
        :param ssh: SSH连接对象
        :param local_file_path: 本地文件路径
        :param remote_file_path: 远程文件存放路径
        '''
        # 创建sftp对象上传文件
        sftp = self.ssh.open_sftp()
        sftp.put(local_file_path,remote_file_path)
        sftp.close()
        
    def download_file(self,remote_file_path,local_file_path):
        '''
        下载文件
        
        :param ssh: SSH连接对象
        :param remote_file_path: 远程文件路径
        :param local_file_path: 本地文件存放路径
        '''
        # 创建sftp对象下载文件
        sftp = self.ssh.open_sftp()
        sftp.get(remote_file_path,local_file_path)
        sftp.close()

def sample():
    '''
    用法示例
    '''
    # 基本信息
    ip = '192.168.xxx.xxx'
    username = '***'
    password = '***'
    
    # 获取SSHUtil对象
    ssh_util = SSHUtil(ip,username,password)
    
    # 执行远程命令
    command = 'ls /home/m2fox'
    print ssh_util.execute_command(command)
    
    # 上传文件
    ssh_util.upload_file('./hello.txt','/home/m2fox/hello.txt')
    
    # 下载文件
    ssh_util.download_file('/home/m2fox/hello.txt','e:/hello.txt')
    print 'end'
    
if __name__ == '__main__':
    sample()

总结

本文讲了paramiko库提供的几项基本功能的用法:建立SSH连接、执行远程命令和上传、下载文件。其实paramiko库还有更多丰富的功能,可以去官方文档进行了解,也可以基于执行远程命令这个基础能力,结合Shell命令、脚本,开发出自己需要的更为丰富的功能,比如批量上传文件、重启远程进程、读取远程配置文件等等,最重要的是学以致用


获取本文源代码:我的GitHub

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容