python调用ssh-paramiko&paramiko-expect

使用 paramiko 类,可以实现python调用ssh

        1. ftp上传下发文件

        2. 执行ssh命令,但是无法一些环境变量无法执行如 cd $AU_TOP,会没有返回

            每次执行shell命令后会关闭会话,下一次调用会打开新的会话,如果执行多条命令可以使用“;”做为分隔符,一次输入执行,如“cd ..;pwd”可以实现移动到上一次文件,打印路径;

         使用 paramiko的exec_command来执行linux命令,不能执行shell,我需要执行ebs的xdf下载生成文件,exec_command会报错。后来发现paramiko-expect可以真实的执行linux命令,说明如下:

        paramiko expect为paramiko ssh库提供类似expect的扩展 它允许脚本通过真正的ssh与主机完全交互 连接。

        类是用ssh客户机对象构造的(这可能是 扩展以支持未来的运输以获得更大的灵活性。

官方文档路径:Client — Paramiko documentation

参考文档:paramiko详解_massoo1的博客-CSDN博客_paramiko

paramiko expect参考:Python paramiko-expect包_程序模块 - PyPI - Python中文网

paramiko expect例子:paramiko-expect/paramiko_expect-demo-helper.py at master · fgimian/paramiko-expect · GitHub

以下为例子:

        getFtpfile和putFtpfile的路径为带文件路径,下载路径如果文件夹路径不存在,会报错,需要使用os类检查下,如果不存在则建立该路径。

import paramiko

class PySSH():
    def __init__(self,ip,port,userName,passWord):
        print('start')
        self.ip = ip
        self.port = port
        self.userName = userName
        self.passWord = passWord
        #print('-->>' + self.ip+self.port+self.userName+self.passWord)

    def executeCommand(self,command):
        print(command)
        #print(self.ip+self.port+self.userName+self.passWord)
        try:
            # 创建sshClient实例对象
            ssh = paramiko.SSHClient()
            # 设置信任远程机器,允许访问
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            # set_missing_host_key_policy
            '''
            设置远程服务器没有在know_hosts文件中记录时的应对策略。目前支持三种策略:
            AutoAddPolicy 自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
            WarningPolicy 用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
            RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
            '''
        except:
            print("There is an error with the SSHClient")
        try:
            # 设置ssh远程连接机器,参数依次为地址、端口、用户名、密码,ssh端口默认22
            print(self.ip,self.port,self.userName,self.passWord)
            ssh.connect(self.ip,#"10.10.11.110",
                        self.port,#
                        self.userName,#"appndev",
                        self.passWord#"appndev"
                        )
            # ssh.connect("10.10.11.110",
            #             "22",
            #             "appndev",
            #             "appndev")
            '''
            connect参数详解:
            hostname 连接的目标主机,该项必填
            port=SSH_PORT 指定端口
            username=None 验证的用户名
            password=None 验证的用户密码
            pkey=None 私钥方式用于身份验证
            key_filename=None 一个文件名或文件列表,指定私钥文件
            timeout=None 可选的tcp连接超时时间
            allow_agent=True, 是否允许连接到ssh代理,默认为True 允许
            look_for_keys=True 是否在.ssh文件夹中搜索私钥文件,默认为True 允许
            compress=False, 是否打开压缩
            '''
            '''
            基于密钥连接
            关于SSH密钥链接大家可以参考我的这篇博客:https://www.cnblogs.com/victoryhan/p/16417898.html
            这里只专注于客户端Python代码的实现。
            #导入私钥
            privateKey = paramiko.RSAKey.from_private_key_file('./id_rsa')
            ssh.connect('ip',22,'username',pkey=privateKey)
            '''
            '''
            基于私钥字符串连接
            #私钥字符串就是私钥的内容,位置在这篇博文里有介绍:https://www.cnblogs.com/victoryhan/p/16417898.html
            keyStr = '[私钥内容]'
            privateKey = paramiko.RSAKey(file_obj=StringIO(keyStr))
            ssh.connect('ip','22','username',pkey=privateKey)
            '''
            print("success to connect to remote server")
        except:
            print("Failed to connect to remote server")

        '''
        执行linux命令
        '''
        try:
            # 设置代表需要执行的linux命令的变量,多条命令用分号隔开
            # order = "ls /"
            #order = "pwd /"
            # 每次执行命令会返回三个对象,对应标准输入、标准输出、标准错误。每调用一次exec_command方法就相当于重新打开一次linux终端,终端环境都是新的。
            #stdin, stdout, stderr = ssh.exec_command(order)
            stdin, stdout, stderr = ssh.exec_command(command)
            # 如果使用了sudo命令请启用下面的代码并填入对应的密码
            # stdin.write("passwd")
            # stdin.flush()
            # 打印输出结果
            print(stdout.readlines())
            # 打印命令执行错误信息
            print(stderr.readlines())
            print('success to carry out command')
        except:
            print('Fail to carry out command')
        # 关闭ssh链接
        ssh.close()

    def getSftp(self):
        transport = paramiko.Transport((self.ip, self.port))  # 注意啊,必须是数字22而不是'22',
        print('print 1')
        transport.connect(username=self.userName, password=self.passWord)  # 需要 用username=和password=,如果只输入值的话,会报错
        sftp = paramiko.SFTPClient.from_transport(transport)
        return sftp#,transport

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

    #上传附件
    def putFtpfile(self,fromPath,toPath):
        transport = paramiko.Transport((self.ip, self.port))  # 注意啊,必须是数字22而不是'22',
        print('print 1')
        transport.connect(username=self.userName, password=self.passWord)  # 需要 用username=和password=,如果只输入值的话,会报错
        sftp = paramiko.SFTPClient.from_transport(transport)
        #sftp = getSftp()
        # 上传
        # sftp.put('[localpath]','[remotepath]')
        #sftp.put('D:\\Users\\brayden.liu\\Documents\\erp-items.txt', '/home/appndev/erp-items.txt')
        sftp.put(fromPath, toPath)
        transport.close()

    #下载附件
    def getFtpfile(self,fromPath,toPath):
        transport = paramiko.Transport((self.ip, self.port))  # 注意啊,必须是数字22而不是'22',
        print('print 1')
        transport.connect(username=self.userName, password=self.passWord)  # 需要 用username=和password=,如果只输入值的话,会报错
        sftp = paramiko.SFTPClient.from_transport(transport)

        # 下载
        #sftp.get('/home/appndev/L8136560.log','D:\\Users\\brayden.liu\\Documents\\L8136560.log')
        sftp.get(fromPath, toPath)
        transport.close()

    def putFtpDir(self,fromPath,toPath,name):
        #确认ftp是否有该文件夹,没有则创建
        try:
            # 创建sshClient实例对象
            ssh = paramiko.SSHClient()
            # 设置信任远程机器,允许访问
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        except:
            print("There is an error with the SSHClient")
        try:
            # 设置ssh远程连接机器,参数依次为地址、端口、用户名、密码,ssh端口默认22
            print(self.ip,self.port,self.userName,self.passWord)
            ssh.connect(self.ip,#"10.10.11.110",
                        "22",#self.port,#
                        self.userName,#"appndev",
                        self.passWord#"appndev"
                        )
            print("success to connect to remote server")
        except:
            print("Failed to connect to remote server")

        '''
        执行linux命令
        '''
        try:
            # 设置代表需要执行的linux命令的变量,多条命令用分号隔开
            order = "ls /"
            #order = "pwd /"
            # 每次执行命令会返回三个对象,对应标准输入、标准输出、标准错误。每调用一次exec_command方法就相当于重新打开一次linux终端,终端环境都是新的。
            print('shell')
            stdin, stdout, stderr = ssh.exec_command('cd BRAYDEN20230213001xx;pwd',get_pty=True)
            print('ls')
            stdin, stdout, stderr = ssh.exec_command('cd BRAYDEN20230213001xx;ls',get_pty=True)
            print(stdout.readlines())
            print('execute')
            stdin, stdout, stderr = ssh.exec_command('cd BRAYDEN20230213001xx;perl download.pl /',get_pty=True)
            print(stdout.readlines())
            print('pwd')
            stdin, stdout, stderr = ssh.exec_command('pwd /')
            print(stdout.readlines())
            stdin, stdout, stderr = ssh.exec_command(order)
            # 如果使用了sudo命令请启用下面的代码并填入对应的密码
            # stdin.write("passwd")
            # stdin.flush()
            # 打印输出结果
            print('pirnt-->1')
            print(stdout.readlines())
            # 打印命令执行错误信息
            #print(stderr.readlines())
            print('pirnt-->2')
            if "allen" in stdout.readlines():
                print('ssss')
            else:
                print('eeee')
            for i in stdout:
                print(stdout[i])
            print('success to carry out command')
        except:
            print('Fail to carry out command')

        ssh.close()
        #遍历来源路径文集,上传文件

    #获取各种文件的路径
    def getPath(self,topName,objType):
        try:
            # 创建sshClient实例对象
            ssh = paramiko.SSHClient()
            # 设置信任远程机器,允许访问
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        except:
            print("There is an error with the SSHClient")
        try:
            # 设置ssh远程连接机器,参数依次为地址、端口、用户名、密码,ssh端口默认22
            print('server info :' , self.ip,self.port,self.userName,self.passWord)
            ssh.connect(self.ip,#"10.10.11.110",
                        self.port,#
                        self.userName,#"appndev",
                        self.passWord#"appndev"
                        )
            print("success to connect to remote server")
        except:
            print("Failed to connect to remote server")

        '''
        执行linux命令
        '''
        try:
            # 设置代表需要执行的linux命令的变量,多条命令用分号隔开
            order = "cd " + topName +  ";pwd"
            #order = "pwd"
            # 每次执行命令会返回三个对象,对应标准输入、标准输出、标准错误。每调用一次exec_command方法就相当于重新打开一次linux终端,终端环境都是新的。
            print('shell-->' + order)
            stdin, stdout, stderr = ssh.exec_command('echo $AU_TOP',get_pty=True)
            #stdin, stdout, stderr = ssh.exec_command('cd /data/ndev/apps/apps_st/appl/au/12.0.0;pwd')
            # 如果使用了sudo命令请启用下面的代码并填入对应的密码
            # stdin.write("passwd")
            # stdin.flush()
            # 打印输出结果
            print('pirnt-->1')
            print(stdout.readlines())
            # 打印命令执行错误信息
            #print(stderr.readlines())
            print('pirnt-->2')
            if "allen" in stdout.readlines():
                print('ssss')
            else:
                print('eeee')
            for i in stdout:
                print(stdout[i])
            print('success to carry out command')
        except:
            print('Fail to carry out command')

        ssh.close()
if __name__ == '__main__':
    #text_create()
    ssh = PySSH('10.10.11.110',22,'用户','密码')
    #ssh.putFtpDir('123','4565','dd')
    #ssh.getPath('/data/ndev/apps/apps_st/appl/au/12.0.0/forms/ZHS','FORM')
    ssh.getFtpfile()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值