越来越觉得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,然后安装:
(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"