使用Python进行SSH远程连接操作

一、ssh连接、执行命令、打印输出

import paramiko

# 创建SSH客户端
client = paramiko.SSHClient()

# 自动添加主机名和密钥到本地的known_hosts文件
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 连接到远程主机
client.connect('远程主机IP', username='用户名', password='密码')

# 执行命令
stdin, stdout, stderr = client.exec_command('要执行的命令')

# 打印命令的输出
print(stdout.read().decode())
# 封装成函数时可以:
# return stdout.read().decode('utf-8', errors='ignore'), stderr.read().decode('utf-8', errors='ignore'), 

注意:

        exec_command每次通过开一个新的Channel来执行传输的命令,因此只能执行一条命令,也就是说第一行执行exec_command("cd xxx"),第二行想在第一行cd的基础上执行exec_command(tar -xzvf xxx)是不行的,因为每次执行完都会回到根目录,所以无法第一次cd切换路径,第二次去该路径进行操作

        解决方法:在exec_command中一次执行多个命令,把要执行的命令之间用 \n 分开,且最后一个命令后不要带\n

import paramiko

# cd到一个目录后进行压缩包解压
stdin, stdout, stderr = client.exec_command("cd /hone/documents\n tar -xzvf abc.tar.gz")

# 如果涉及到入参拼接,\n怎么放
# cd进去,再cd进解压后的文件夹,最后执行安装
file_path = /home/documents
folder= abc
stdin, stdout, stderr = client.exec_command("cd " + file_path + "\n cd " + abc + "\n bash install.sh")

二、如何保持shell窗口一直连接状态

        exec_command每次执行后都会退出当前的shell

        如果想在当前的shell下根据输出提示持续输出(比如密码卸载、ftp传输文件、vim等),此时就需要使用invoke_shell

import paramiko
import time

# 创建连接、添加密钥、远程的操作见上面的介绍,此处省略...
# 封装一个ftp传输文件的函数
def ftp_trans_file():
    ftp_file_path = "/home/user/文件集"
    ftp_file_name = "123.txt"
    ftp_host = 10.xx.xx.xx
    ftp_username = aaa
    ftp_password = 123456

    shell = client.invoke_shell()
    shell.send("cd " + ftp_file_path + "\n ftp\n")  # cd到文件目录下,输入ftp,第一个\n用于连续执行两条命令,第二个\n是用于输入ftp后换行(模拟按下enter键)
    time.sleep(1)
    shell.send("open " + ftp_host + "\n")  # 打开文件传输ip,并按回车
    time.sleep(1)
    shell.send(ftp_username + "\n")  # 输入用户名
    time.sleep(1)
    shell.send(ftp_password + "\n")  # 输入密码
    time.sleep(1)
    shell.send("put " + ftp_file_name + "\n")  # 输入密码
    time.sleep(1)
    data = shell.recv(9999).decode('utf-8')  # 获取传输文件前后所有的提示语
    shell.send('exit\n')  # 退出
    shell.close()  # 关闭
    return data

扩展:

        shell模拟enter键:shell.send("\n")

        shell模拟esc键:shell.sned("\x1b")

三、补充

1、exec_command与invoke_shell的区别

        invoke_shell使用的是SSH shell channel的方式执行,具备持久化能力,类似于MobaXterm,

        shell命令用exec_command

        shell脚本用invoke_shell

2、使用invoke_shell的情况下,获取值,处理后再给值(密码卸载)

        将shell.recv放在中间,上面的shell.recv放在了最后,是接收了所有消息

import paramiko
import time

# 创建连接、添加密钥、远程的操作见上面的介绍,此处省略...
# 封装一个ftp传输文件的函数
def ftp_trans_file():
    shell = client.invoke_shell()
    shell.send("cd /usr/local/bin\n ./unins\n")  # cd到卸载目录下,输入./unins,第一个\n用于连续执行两条命令,第二个\n是用于输入./unins后换行(模拟按下enter键)
    time.sleep(2)
    data = shell.recv(9999).decode('utf-8')  # 获取系统返回的那一行的信息
    text = data.split()[-1]  # 括号内不给值表示默认从空格、换行进行切割
    print(text)  # 获取到了卸载码
    # 以下应该要把卸载码取出后回win上进行生成执行码,然后将执行码继续输入执行卸载,省略...
    shell.send('exit\n')  # 退出
    shell.close()  # 关闭
    return data

物联沃分享整理
物联沃-IOTWORD物联网 » 使用Python进行SSH远程连接操作

发表评论