很多产品的服务端都是运行在 Linux 操作系统上的。

做 自动化测试 或者 运维工作的朋友,经常需要 控制远程 Linux 主机。

比如:自动安装环境 、执行自动化测试的一些步骤、数据的自动获取和分析。。。

一、paramiko简介 

 paramiko是python第三方库,可以用来远程操作 Linux系统(通过ssh协议)。

下载方式

1、使用豆瓣源

pip install paramiko –i https://pypi.douban.com/simple/ --trusted-host pypi.douban.com

2、直接下载

pip install paramiko

二、paramiko怎么使用

本文假设你的Linux主机IP地址是 192.168.0.106 ,用户名为 root,密码为 rootmima

import paramiko

# 创建SSHClient 实例对象
ssh = paramiko.SSHClient()

# 设置信任远程机器,允许访问
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# ssh连接远程机器,参数为  地址、端口、用户名、密码
ssh.connect("192.168.0.106", 22, "root", "password")

# 执行命令,创建目录 logs
ssh.exec_command("mkdir logs")

# 关闭ssh连接
ssh.close()

执行完上面的程序,就会发现远程的Linux主机,多出了一个目录,名为 logs

三、获取屏幕输出 

 自动化程序经常 要根据 输出的结果进行判断分析,然后决定下一步怎么做。

比如, 我们要杀死 服务进程, 必须执行ps命令 得到这个进程的ID,才能执行后面的kill命令。

import paramiko

# 创建SSHClient 实例对象
ssh = paramiko.SSHClient()

# 设置信任远程机器,允许访问
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# ssh连接远程机器,参数为  地址、端口、用户名、密码
ssh.connect("192.168.0.106", 22, "root", "password")

cmd = 'ps -ef|grep apiserver |grep -v grep'

# 每次执行命令会返回3个对象,对应标准输入、标准输出、标准错误
stdin, stdout, stderr = ssh.exec_command(cmd)

# 从 标准输出、标准错误 中读取字节
outputBytes = stdout.read()+ stderr.read()

# 解码为字符串
outputStr = outputBytes.decode('utf8')

print(outputStr)

这个代码就可以打印出  正在运行的进程

 三、命令的前后关联

请大家执行以下代码

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.0.106", 22, "root", "password")

# 创建目录 testdir
ssh.exec_command("mkdir testdir")

# 进入目录 testdir
ssh.exec_command("cd testdir")

# 查看当前路径
stdin, stdout, stderr = ssh.exec_command("pwd")
print(stdout.read())

ssh.close()

大家会惊奇的发现打印处理目录不是  /root/testdir,而是  /root

难道 cd  testdir 这命令没有起作用吗?

注意 exec_command 是每次执行都是 新打开一个channel的东西执行,

每个channel都是命令执行的环境,每执行命令都是一个新的执行环境,不在上次执行的环境里面.

相当于 每次都在各自的执行环境里面,和前面的执行环境没有关系。

那么怎么办呢?

可以: 多个命令一起执行,用分号隔开,像这样

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.0.106", 22, "root", "rootmima")

# 创建目录 testdir
ssh.exec_command("mkdir testdir")

# 用一行命令 进入目录 testdir 并且 查看当前路径
stdin, stdout, stderr = ssh.exec_command("cd testdir;pwd")
print(stdout.read())

ssh.close()

四、 文件传输

有时,我们需要和远程Linux机器之间互相传输文件,包括上传和下载。

比如 自动安装测试环境,经常需要把产品的安装包传送到远程机器上。

paramiko 库提供了 传送文件的方法,如下所示

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.0.106", 22, "root", "password")

# 打开一个sftp连接,返回sftp连接对象
sftp = ssh.open_sftp()

# put方法上传文件,第1个参数是本地路径,第2个参数是远程路径
sftp.put('install.zip', '/root/install.zip')

# get方法下载文件,第1个参数是远程路径,第2个参数是本地路径
sftp.get('/root/log.zip', 'd:/log.zip')

# 关闭sftp连接
sftp.close()

# 关闭ssh连接
ssh.close()

注意:

使用put方法上传文件时,第2个参数是远程路径,当前登录的用户必须有该路径的写权限

使用get方法上传文件时,第1个参数是远程路径,当前登录的用户必须有该路径的读权限