越来越觉得python的强悍,因为有太多python的第三方库,可以实现太多的功能。本篇就介绍一个第三方库,利用python来操作linux系统中的脚本命令或者直接执行脚本。这个库的名称为paramiko,好像没法言明之意,其github网址为:


https://github.com/paramiko/paramikogithub.com

Paramiko是用来做什么的呢?主要用于基于SSH协议连接远程机器。例如有一台云服务器,或者自己有一个虚拟机上安装了linux操作系统,当我们启动了linux操作系统后,如果不习惯或者不喜欢直接在linux的终端上进行命令行操作,就可以使用paramiko模块中的方法,在python软件中来操作linux机器。当然是用这个的基础,必须有python,必须有安装有linux操作系统、可以远程连接、安装SSH协议的机器。之前介绍过云服务器的使用方法,可以在本地电脑上安装SSH SECURE CLIENT这种终端管理工具连接云服务器,进入云服务器进行操作。不过这这种方式还是在linux里操作。而使用paramiko模块,是在python环境中远程操作linux系统。

(1)paramiko安装

与其他第三方库一样,在安装时使用python的pip工具。也可以如下在pycharm中选择当前项目的setting,在解释器窗口添加模块,选择paramiko,然后安装:


python远程调用stabled diffusion python远程调用centos命令_python paramiko模块下载


(2)paramiko基本使用方法

paramiko模块主要包含两个核心组件:SSHClient和SFTPClient。SSHClient的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用于执行远程命令。SFTPClient的作用类似与Linux的sftp命令,是对SFTP客户端的封装,用以实现远程文件操作,如文件上传、下载、修改文件权限等操作。

对于SSHClient部分,主要使用步骤如下:


import paramiko
#1.新建一个连接对象
client = paramiko.SSHClient()
#2.设置连接策略,保存服务器主机和密钥信息
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#3.建立连接,设定远程机器的ip地址,端口号,用户名,密码
client.connect(hostname='192.168.58.159',port=22,username='root',password='root123')
#4.连接成功后,可以使用exec_command来执行linux命令,同时可以返回连接结果
res = client.exec_command(cmd=shellCMD)
#5.关闭连接
client.close()


我们来测试一下,按照上述代码,将第4步的命令替换为:


import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname='192.168.58.160',port=22,username='root',password='root123')
stdin,stdout,stderr = client.exec_command('ls -l')
print(stdout.read().decode('utf-8'))
client.close()


执行后在pycharm的终端显示运行结果:


F:learn-Pythonweb2020-stavenvScriptspython.exe F:/learn-Python/web2020-sta/jobs/paraShell.py
total 32
-rw-------. 1 root root  1424 Feb  8 17:42 anaconda-ks.cfg
-rw-r--r--. 1 root root 25548 Apr  7  2017 mysql57-community-release-el7-10.noarch.rpm


代码中使用了linux命令ls -l,这是文件列表显示的脚本命令。执行代码后就将centos系统root用户目录下的文件全部列举出来了。而我们并没有进入centos系统里进行操作。不过由于这种命令操作都是较为简短的,太长或者太复杂的这样操作肯定不合适。

下面将上述代码封装一下:


import paramiko,logging

class ShellExec():
    #初始化配置连接参数和连接对象
    def __init__(self,hostname = None, port= None,username = None, password = None):
        self.hostname = hostname
        self.port = port
        self.username = username
        self.password = password
        self.client = paramiko.SSHClient()

    #实现远程机器的连接
    def ssh_connect(self):
        flag = True
        try:
            self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
            self.client.connect(hostname=self.hostname,port=self.port,username=self.username,password=self.password)
        except Exception as e:
            flag = False
        return flag

    #执行shell命令,cmd为shell命令参数
    def exec_cmd(self,shell_cmd=None):
        stdin,stdout,stderr = self.client.exec_command(shell_cmd)
        return stdout.read().decode('utf-8')

    #关闭连接
    def ssh_close(self):
        self.client.close()

if __name__=='__main__':
    client = ShellExec(hostname='192.168.58.160',port=22,username='root',password='root123')
    if client.ssh_connect():
        result = client.exec_cmd(shell_cmd='crontab -l')
        if not result:
            print("执行成功!")
        else:
            print("执行结果为: n" + result)
        client.ssh_close()
    else:
        logging.warning("the server is not connected!please check your parameters")


这样封装好后,只要输入连接参数和执行的shell命令,就可以得到想要的结果。例如使用这个模块,实现在root账户下新建一个文件,传入touch test.txt即可。运行结束后,再传入一个ls -l命令,就可以获得如下结果:


执行结果为: 
total 32
-rw-------. 1 root root  1424 Feb  8 17:42 anaconda-ks.cfg
-rw-r--r--. 1 root root 25548 Apr  7  2017 mysql57-community-release-el7-10.noarch.rpm
-rw-r--r--. 1 root root     0 Feb 14 18:00 test.txt


如此在服务器linux上许多操作都可以使用python来完成了。

对于SFTPClient部分,主要使用步骤方法如下:


import os,logging
# 获取Transport实例
client = paramiko.Transport(('192.168.58.160', 22))
# 连接SSH服务端,使用password
client.connect(username='root', password='root123')
#获取sftp实例,传入连接对象
print("connecting ... ")
#制定访问目标服务器路径
remotepath = '/home/hadoop/sources/1.py'
localpath = 'f:/learn-Pythn/web2020-sta/jobs/1.py'
try:
    #建立ftp连接
    sftp = paramiko.SFTPClient.from_transport(client)
    #读取目标路径下的所有文件
    files= sftp.listdir(remotepath)
    for file in files:
        print(file)
    #将服务器目标路径中文件下载到指定的磁盘位置
    sftp.get(remotepath,localpath)
    #将本次磁盘文件上传到服务器指定路径中文件
    sftp.put(localpath,remotepath)
    logging.info("successful download!or upload!")
    client.close()
except:
    print('连接失败......')


如sshclient一样,也可以将上述代码封装一下方便使用:


import paramiko,logging

class FTPExec():
    #初始化配置连接参数和连接对象
    def __init__(self,hostname = None, port= None,username = None, password = None):
        self.hostname = hostname
        self.port = port
        self.username = username
        self.password = password        

    #实现远程机器的连接
    def ssh_connect(self):
        flag = True
        try:
            self.client = paramiko.Transport((self.hostname, self.port))
            self.client.connect(username=self.username,password=self.password)
        except Exception as e:
            flag = False
        return flag

    #执行put/get命令,put命令为上传,get命令为下载
    def exec_ftp(self,action=None,localpath=None,remotepath=None):
        # 获取SFTP实例
        sftp = paramiko.SFTPClient.from_transport(self.client)
        # 执行上传动作
        if action=='upload':
            sftp.put(localpath, remotepath)
        # 执行下载动作
        elif action == 'download':
            sftp.get(remotepath, localpath)

    #关闭连接
    def ssh_close(self):
        self.client.close()

if __name__=='__main__':
    client = FTPExec(hostname='192.168.58.160',port=22,username='root',password='root123')
    if client.ssh_connect():
        result = client.exec_ftp(action='download',localpath='data/test.py',remotepath='home/hadoop/test.py')
        if not result:
            print("执行成功!")
        else:
            print("执行结果为: n" + result)
        client.ssh_close()
    else:
        logging.warning("the server is not connected!please check your parameters"