paramiko模块——ssh远程连接服务器并执行命令

paramiko模块——ssh远程连接服务器并执行命令

通过ssh远程连接服务器并执行相应的命令,类似于Xshell

ansible用来批量管理远程服务器,底层其实用的就是paramiko模块

安装

pip3 install paramiko

使用

paramiko模块即支持用户名密码的方式操作服务器

也支持公钥私钥的方式操作服务器

并且实际生产中公钥私钥用的较多,因为密码是敏感信息

用户名和密码的方式执行命令

"""执行命令  用户名和密码的方式"""
# 创建对象
ssh = paramiko.SSHClient()
# 允许链接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())


# 链接服务器
ssh.connect(hostname='172.16.219.173',port=22,username='root',password='zgh123456')

# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls /')
"""
stdin用来输入额外的命令 
    yum install ansible  额外的命令-y
stdout命令的返回结果  正确
stderr命令的返回结果  错误
"""
res = stdout.read()  # 网络传输过来的二进制数据
print(res.decode('utf-8'))

# 关闭链接
ssh.close()

公钥和私钥的方式执行命令

公钥和私钥需要通过git命令生成参考之前写的git相关文章:

https://www.cnblogs.com/ghylpb/p/12158061.html

# 公钥和私钥(先讲公钥保存到服务器上)
import paramiko

# 读取本地私钥(公钥和私钥需要)
private_key = paramiko.RSAKey.from_private_key_file('a.txt')

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='172.16.219.173', port=22, username='root', pkey=private_key)

# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls /')
# 获取命令结果
result = stdout.read()
print(result.decode('utf-8'))
# 关闭连接
ssh.close()

用户名和密码的方式上传下载文件

"""上传下载文件  用户名和密码的方式"""
import paramiko

# 用户名和密码
transport = paramiko.Transport(('172.16.219.173', 22))
transport.connect(username='root', password='zgh123456')

sftp = paramiko.SFTPClient.from_transport(transport)

# 上传文件
# sftp.put("a.txt", '/data/b.txt')  # 注意上传文件到远程某个文件下 文件必须存在

# 下载文件
sftp.get('/data/b.txt', 'c.txt')  # 将远程文件下载到本地并重新命令
transport.close()

公钥私钥的方式上传下载文件

"""上传下载文件 公钥私钥的方式"""
# 公钥和私钥
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('c.txt')
transport = paramiko.Transport(('172.16.219.173', 22))
transport.connect(username='root', pkey=private_key)
sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
# sftp.put('manage.py', '/data/temp.py')

# 将remove_path 下载到本地 local_path
# sftp.get('remove_path', 'local_path')
transport.close()

将上传下载执行命令进行封装

"""
我现在即想执行命令又想上传下载文件并且多次执行
yum install ansible
yum install redis
yum install redis
upload

单链接下完成多步操作
"""
# 下面写的类 你只要只要是想通过paramiko链接服务器都可以使用
import paramiko


class SSHProxy(object):
    def __init__(self, hostname, port, username, password):
        self.hostname = hostname
        self.port = port
        self.username = username
        self.password = password
        self.transport = None

    def open(self):  # 给对象赋值一个上传下载文件对象连接
        self.transport = paramiko.Transport((self.hostname, self.port))
        self.transport.connect(username=self.username, password=self.password)

    def command(self, cmd):  # 正常执行命令的连接  至此对象内容就既有执行命令的连接又有上传下载链接
        ssh = paramiko.SSHClient()
        ssh._transport = self.transport

        stdin, stdout, stderr = ssh.exec_command(cmd)
        result = stdout.read()
        return result

    def upload(self, local_path, remote_path):
        sftp = paramiko.SFTPClient.from_transport(self.transport)
        sftp.put(local_path, remote_path)
        sftp.close()

    def close(self):
        self.transport.close()

    def __enter__(self):  # 对象执行with上下文会自动触发
        # 
        # print('触发了enter')
        self.open()
        return self  # 这里发挥上面with语法内的as后面拿到的就是什么
        # return 123


    def __exit__(self, exc_type, exc_val, exc_tb):  # with执行结束自动触发
        # print('触发了exit')
        self.close()
"""
上面这个类在使用的时候 需要先执行open方法
obj = SSHProxy()
obj.open()  文件对象 链接服务器

obj.command()
obj.command()
obj.upload()
obj.upload()

obj.close()  关闭链接

文件操作
f = open()
f.write()
f.read()
f.close()

with上下文管理
with open() as f:
...
"""

# 对象默认是不支持with语法的   
# obj = SSHProxy('172.16.219.173',22,'root','zgh123456')
# with obj as f:
#     # print('进入with代码块')
#     print(f)

if __name__ == '__main__': 
    with SSHProxy('172.16.219.173',22,'root','zgh123456') as ssh:
        ssh.command()
        ssh.command()
        ssh.command()
        ssh.upload()
posted @ 2020-03-17 21:49  ylpb  阅读(796)  评论(0编辑  收藏  举报