Python/通过paramiko远程链接Linux服务器进行操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39591494/article/details/89493727

paramiko远程链接Linux服务器进行操作


  在平时链接Linux服务器进行远程操作时可以通过SecureCRT or Xshell工具通过ssh协议对Linux进行操作指令,上传文件、下载文件等操作。 在上一篇文章中通过python中的subprocess模块对Linux进行操作,本章将通过windows主机远程Linux服务器,对Linux进行命令操作,同时上传、下载文件操作。

Paramiko是用python语言写的一个模块,远程连接到Linux服务器,查看上面的日志状态,批量配置远程服务器,文件上传,文件下载等操作。

本文没有太多专业术语,目的:对Linux服务器进行远程命令操作,望读者可以参考本文一起执行代码并完成,若电脑没在旁边,您可以选择收藏此文章。

一、连接服务器


1.1、连接Linux服务器定义的参数

在连接服务器之前首先需要知道服务器的地址(通常用ip来定义),远程服务器的端口、用户名以及密码。 如下定义:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

HOST = "172.20.10.5" # 远程服务器的IP地址
USER = "root" # 远程服务器的用户名
PWD = "pwd123" # 远程服务器的密码
PORT = 22 # 远程服务器的端口号

本章使用paramiko模块对Linux服务器进行操作,所以需要安装paramiko模块

(yankerp) C:\Users\Yankerp>pip install paramiko # 通过pip安装paramiko
(yankerp) C:\Users\Yankerp>conda install paramiko # 通过conda 安装paramiko

安装结束之后通过import paramiko 导入此模块

1.2、SSHClient类:

在paramiko模块中有一个SSHClient类。A high-level representation of a session with an SSH server. This class wraps .Transport, .Channel, and .SFTPClient to take care of most aspects of authenticating and opening channels. A typical use case is: 这个类使用SSH服务器的会话的高级表示。这个类封装了. transport、. channel和. sftpclient来处理验证和打开通道方面。通过SSHClient类中的一些方法对Linux进行操作及控制。

实例化SSHClient类生成对象Client

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22

Client = paramiko.SSHClient() # 实例化一个对象Client 在这里Client为自定义

通过SSHClient中的connect方法连接
connect(hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, auth_timeout=None, gss_trust_dns=True, passphrase=None)
以上为SSHClient中connect方法中的参数:(尝试连接 如下:)

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22

Client = paramiko.SSHClient()
Client.connect(hostname=HOST, port=PORT, username=USER, password=PWD)
>>>
Traceback (most recent call last):  File "f:/Python_yanzan2018/YanKai_network programming/YanKai_paramiko03/core/paramiko_01.py", line 9, in <module>
    Client.connect(hostname=HOST, port=PORT, username=USER, password=PWD)
  File "C:\ProgramData\Miniconda3\envs\yankerp\lib\site-packages\paramiko\client.py", line 407, in connect
    self, server_hostkey_name, server_key
  File "C:\ProgramData\Miniconda3\envs\yankerp\lib\site-packages\paramiko\client.py", line 809, in missing_host_key
    "Server {!r} not found in known_hosts".format(hostname)
paramiko.ssh_exception.SSHException: Server '172.20.10.5' not found in known_hosts

paramiko.ssh_exception.SSHException: Server ‘172.20.10.5’ not found in known_hosts

paramiko.ssh_exception。SSHException:服务器'172.20.10.5'未在known_hosts中找到

解决办法:
允许连接不在know_hosts文件中的主机
.set_missing_host_key_policy(paramiko.AutoAddPolicy())

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22

Client = paramiko.SSHClient()
Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
Client.connect(hostname=HOST, port=PORT, username=USER, password=PWD)
>>> 成功运行.......

可以成功连接后改写成function 如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22

def connect_linux(HOST, PORT, USER, PWD):
    Client = paramiko.SSHClient()
    try:
        Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        Client.connect(HOST, PORT, USER, PWD)
    except Exception as e:
        print(e)
    return Client

print(connect_linux(HOST, PORT, USER, PWD))
>>> <paramiko.client.SSHClient object at 0x0000026992D27320> # 返回了paramiko.client.SSHClient 对象

在以上代码运行结果返回:paramiko.client.SSHClient 对象,接下来就可以通过这个对象来对Linux执行操作。

二、对服务器进行操作


2.1、通过exec_command方法对Linux服务器进行操作

exec_command(command, bufsize=-1, timeout=None, get_pty=False, environment=None)
Execute a command on the SSH server. A new Channel is opened and the requested command is executed. The command’s input and output streams are returned as Python file-like objects representing stdin, stdout, and stderr.(在SSH服务器上执行命令。打开一个新通道并执行请求的命令。命令的输入和输出流作为类Python文件对象返回,表示stdin、stdout和stderr。)

exec_command Returns: (the stdin, stdout, and stderr of the executing command, as a 3-tuple)
在执行exec_command 返回的结果为:执行命令的stdin、stdout和stderr,作为一个3元组。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22


def connect_linux(HOST, PORT, USER, PWD):
    Client = paramiko.SSHClient()
    try:
        Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        Client.connect(HOST, PORT, USER, PWD)
    except Exception as e:
        print(e)
    return Client

cmd_linux = connect_linux(HOST, PORT, USER, PWD)
stdin, stdout, stderr = cmd_linux.exec_command("df -h")
print(stdout.read().decode())
>>>
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   50G  2.5G   48G   5% /
devtmpfs                 903M     0  903M   0% /dev
tmpfs                    913M     0  913M   0% /dev/shm
tmpfs                    913M  8.6M  904M   1% /run
tmpfs                    913M     0  913M   0% /sys/fs/cgroup
/dev/mapper/centos-home  146G   33M  146G   1% /home
/dev/sda1                497M  125M  373M  26% /boot
tmpfs                    183M     0  183M   0% /run/user/0
对代码再次加强
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22


def connect_linux(HOST, PORT, USER, PWD):
    """测试链接Linux函数,Client = paramiko.SSHClient()
    """
    Client = paramiko.SSHClient()
    try:
        Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        Client.connect(HOST, PORT, USER, PWD, timeout=5)
    except Exception as e:
        print(e)
    return Client


def cmd_linux(client, cmd):
    """将远程执行的Linux命令结果返回:stdin, stdout, stderr (stdout)并decode输出...
    """
    stdin, stdout, stderr = client.exec_command(cmd)
    print(stdout.read().decode())
    return stdout


def main():
    """设置远程执行Linux操作命令输入...
    """
    client = connect_linux(HOST, PORT, USER, PWD)
    while True:
        cmd = input("请您输入需要执行的命令(空为退出):").strip()
        if cmd == "":
            return False
        else:
            cmd_linux(client, cmd)

if __name__ == "__main__":
    main()

运行过程如下:
在这里插入图片描述两张图解释:
在这里插入图片描述
在这里插入图片描述以下红色部分为第一次运行,黄色部分为第一次运行成功后
在这里插入图片描述

三、远程连接服务器并上传下载文件


在以上代码中通过了paramiko.exec_command方法连接到linux服务器并且对服务器进行了相关的操作,接下来将通过另外的方法对服务器进行上传下载文件等操作。通过.open_sftp对linux进行文件上传下载操作。

3.1、定义文件路径并上传

在做上传操作的时候,首先需要连接到Linux服务器,随后定义源文件以及目标文件,也就是从哪传到哪如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-


import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22

windows_file = r"F:\paramiko_data\yankerp.txt"
linux_file = r"/root/data/yankerp.txt"

Client = paramiko.SSHClient()
Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
Client.connect(HOST, PORT, USER, PWD)

定义完成之后调用open_sftp()方法进行操作,如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-


import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22

windows_file = r"F:\paramiko_data\yankerp.txt"
linux_file = r"/root/data/yankerp.txt"

Client = paramiko.SSHClient()
Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
Client.connect(HOST, PORT, USER, PWD)
# -------------------以上为测试连接Linux服务器------------------------
sftp = Client.open_sftp() # 调用Client.open_sftp方法
sftp.put(windows_file, linux_file) # 通过生成的对象sftp.put方法将windows的yankerp.txt 文件传入Linux
3.2、更改为function
#!/usr/bin/env python
# -*- coding:utf-8 -*-


import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22


def connect_linux(HOST, PORT, USER, PWD):
    """测试链接Linux函数,Client = paramiko.SSHClient()
    """
    Client = paramiko.SSHClient()
    try:
        Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        Client.connect(HOST, PORT, USER, PWD, timeout=10)
    except Exception as e:
        print(e)
    return Client


def put_linux(Client, windows_file, linux_file):
    try:
        sftp = Client.open_sftp()
        sftp.put(windows_file, linux_file)
        sftp.close()
        return True
    except Exception as e:
        print(e)


def main():
    Client = connect_linux(HOST, PORT, USER, PWD)
    windows_path = input("请您输入windows文件路径:").strip()
    linux_path = input("请您输入Linux文件路径:").strip()
    if put_linux(Client, windows_path, linux_path):
        print(f"恭喜您,上传{windows_path}文件成功,请在Linux{linux_path}目录下查看...")
    else:
        print("对不起,上传文件失败,请您重试....")
        return False
    
if __name__ == "__main__":
    main()

运行过程如下:
在这里插入图片描述在以上代码中成功的将windows下的某一个文件上传至Linux通过sftp.put(windows_file, linux_file),下载就很简单了,通过.get方法下载即可

#!/usr/bin/env python
# -*- coding:utf-8 -*-


import paramiko

HOST = "172.20.10.5"
USER = "root"
PWD = "pwd123"
PORT = 22


def connect_linux(HOST, PORT, USER, PWD):
    """测试链接Linux函数,Client = paramiko.SSHClient()
    """
    Client = paramiko.SSHClient()
    try:
        Client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        Client.connect(HOST, PORT, USER, PWD, timeout=10)
    except Exception as e:
        print(e)
    return Client


def put_linux(Client, windows_file, linux_file):
    try:
        sftp = Client.open_sftp()
        sftp.put(windows_file, linux_file)
        sftp.close()
        return True
    except Exception as e:
        print(e)


def get_linux(Client, linux_file, windows_file):
    try:
        sftp = Client.open_sftp()
        sftp.get(linux_file, windows_file)
        sftp.close()
        return True
    except Exception as e:
        print(e)


def main_put():
    Client = connect_linux(HOST, PORT, USER, PWD)
    windows_path = input("请您输入windows文件路径:").strip()
    linux_path = input("请您输入Linux文件路径:").strip()
    if put_linux(Client, windows_path, linux_path):
        print(f"恭喜您,上传{windows_path}文件成功,请在Linux系统中的{linux_path}目录下查看...")
    else:
        print("对不起,上传文件失败,请您重试....")
        return False


def main_get():
    Client = connect_linux(HOST, PORT, USER, PWD)
    linux_path = input("请您输入Linux文件路径:").strip()
    windows_path = input("请您输入windows文件路径:").strip()
    if get_linux(Client, linux_path, windows_path):
        print(f"恭喜您,下载{linux_path}文件成功,请在Windows系统中的{windows_path}目录下查看...")
    else:
        print("对不起,下载文件失败,请您重试....")
        return False


def main():
    menu = {
        "1" : "上传文件",
        "2" : "下载文件"
    }
    for k, v in menu.items():
        print(f"{k}、{v}")
    your = input("请您输入:").strip()
    if your == "1":
        main_put()
    elif your == "2":
        main_get()
    
if __name__ == "__main__":
    main()
>>>
1、上传文件
2、下载文件
请您输入:1
请您输入windows文件路径:F:\paramiko_data\users.txt
请您输入Linux文件路径:/usr/local/src/users.txt
恭喜您,上传F:\paramiko_data\users.txt文件成功,请在Linux/usr/local/src/users.txt目录下查看...
------------
1、上传文件
2、下载文件
请您输入:2
请您输入Linux文件路径:/usr/local/src/users.txt
请您输入windows文件路径:F:\user.txt
恭喜您,下载/usr/local/src/users.txt文件成功,请在WindowsF:\user.txt目录下查看...

到这里本章通过windows主机远程Linux服务器,对Linux进行命令操作,同时上传、下载文件操作。已经实现了,希望对您所有帮助,再见~

猜你喜欢

转载自blog.csdn.net/qq_39591494/article/details/89493727