美文网首页
python库实战 - paramiko

python库实战 - paramiko

作者: 许忠慧 | 来源:发表于2020-05-18 10:06 被阅读0次

    paramiko 模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能。

    安装:

    pip install paramiko
    

    一、常用函数说明:

    1.基于用户名和密码的 sshclient 方式登录

    # 建立一个sshclient对象
    ssh = paramiko.SSHClient()
    # 允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 调用connect方法连接服务器
    ssh.connect(hostname='192.168.2.129', port=22, username='super', password='super')
    # 执行命令
    stdin, stdout, stderr = ssh.exec_command('df -hl')
    # 结果放到stdout中,如果有错误将放到stderr中
    print(stdout.read().decode())
    # 关闭连接
    ssh.close()
    

    2.基于用户名和密码的 transport 方式登录

    方法1是传统的连接服务器、执行命令、关闭的一个操作,有时候需要登录上服务器执行多个操作,比如执行命令、上传/下载文件,方法1则无法实现,可以通过如下方式来操作:

    # 实例化一个transport对象
    trans = paramiko.Transport(('192.168.2.129', 22))
    # 建立连接
    trans.connect(username='super', password='super')
    # 将sshclient的对象的transport指定为以上的trans
    ssh = paramiko.SSHClient()
    ssh._transport = trans
    # 执行命令,和传统方法一样
    stdin, stdout, stderr = ssh.exec_command('df -hl')
    print(stdout.read().decode())
    # 关闭连接
    trans.close()
    

    3.基于公钥密钥的 SSHClient 方式登录

    # 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数
    pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
    # 建立连接
    ssh = paramiko.SSHClient()
    ssh.connect(hostname='192.168.2.129',
                port=22,
                username='super',
                pkey=pkey)
    # 执行命令
    stdin, stdout, stderr = ssh.exec_command('df -hl')
    # 结果放到stdout中,如果有错误将放到stderr中
    print(stdout.read().decode())
    # 关闭连接
    ssh.close()
    

    二、实例

    脚本说明:本地上传ipa到签名服务器,调用重签名脚本,然后把重签名后的包再下载到自己本地

    import sys, os
    import paramiko
    
    """
    1.将要重签名的ipa测试包放到脚本的同级目录下
    2.确保脚本所在目录只有一个.ipa后缀的文件
    3.特别注意:ipa的包名中不要含有空格和特殊字符串
    4.以上3步都完成的情况下直接运行脚本即可
    """
    
    
    if __name__ == '__main__':
    
        filePath = os.path.realpath( os.path.dirname(__file__) )            #脚本所在目录
    
        # 删除签名服务器上的旧包先
        ssh = paramiko.SSHClient()                                                                          
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())                                           
        ssh.connect(hostname='127.0.0.1', port=22, username='QA', password='QA')      #这里填自己的       
        stdin, stdout, stderr = ssh.exec_command('rm -rf Desktop/重签名/*.ipa')
        print("已自动删除重签名设备上 Desktop/重签名/ 目录中的ipa包")
        ssh.close()                                                                                         
    
    
        # 上传要签名的文件到重签名mac机文件
        trans = paramiko.Transport(("192.168.93.145", 22))                                                                          
        trans.connect(username='chenshzh', password='youzu.com')                                                                            
        sftp = paramiko.SFTPClient.from_transport(trans)                                                                            
        uploadFile = [fileName for fileName in os.listdir(filePath) if "ipa" in fileName and "signed" not in fileName][0]           
        print("正在将%s上传到签名服务器" %uploadFile)
        sftp.put(localpath=os.path.join(filePath, uploadFile), remotepath='/Users/user/Desktop/重签名/%s' %uploadFile)         
        trans.close()                                                                                                               
        print("上传成功")
        
        # 进行签名操作
        ssh = paramiko.SSHClient()                                                                                                  
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())                                                                   
        ssh.connect(hostname='192.168.93.145', port=22, username='chenshzh', password='youzu.com')                                  # 调用connect方法连接服务器
        print("正在重签名,请稍等...")
        stdin, stdout, stderr = ssh.exec_command('security unlock-keychain -p "youzu.com" ~/Library/Keychains/login.keychain-db && cd /Users/user && python Desktop/重签名/scriptFiles/resignature2.py')       
        print(stdout.read().decode())                                                                                               
        print(stderr.read().decode())                                                                                               
        if "Error" in stderr.read().decode():
            print("自动重签失败,请手动操作重签名看看是哪个环节有问题")
            sys.exit(0)
        print("重签名结束")
        stdin, stdout, stderr = ssh.exec_command('ls -t ~/Desktop/重签名/outputFiles/ | head -1')
        updateFile = stdout.read().decode().strip() #这里一定要加一个strip,一定要,一定要~~~~
        stdin, stdout, stderr = ssh.exec_command('md5 ~/Desktop/重签名/outputFiles/%s' %updateFile)
        updateFileMd5 = stdout.read().decode().strip().split("=")[-1]
        ssh.close()                                                                                                                 
        print("正在将重签名后的包下载到本地,原始包名 = %s, md5 = %s" %(updateFile, updateFileMd5))
    
        # 下载签名后的文件到本地
        trans = paramiko.Transport(("192.168.93.145", 22))                                                                                                                  
        trans.connect(username='chenshzh', password='youzu.com')                                                                                                            
        sftp = paramiko.SFTPClient.from_transport(trans)                                                                                                                    
        sftp.get(remotepath = os.path.join("/Users/user/Desktop/重签名/outputFiles/", updateFile), localpath = os.path.join(filePath, "signed_%s" %uploadFile))        
        localUpdateFileMd5 = os.popen("certutil -hashfile %s MD5" %(os.path.join(filePath, "signed_%s" %uploadFile)))
        trans.close()                                                                                                                                                       
        print("重签名后的包已经下载到脚本所在目录 包名 = signed_%s, md5 = %s" %(uploadFile, localUpdateFileMd5.read().split("\n")[1]))
    
    

    这里有两个坑要特别记录下:

    1. 通过paramiko调用mac机上 重签名脚本进行重签名的时候总是失败,在这个环节上卡了好几天才解决掉。主要报错:
    errSecInternal signature
    

    这是由于mac的安全机制导致的。ssh方式连接到mac机,默认是没有账户的,但是访问钥匙串要求必须有用户身份,所以需要添加一步输入密码解锁钥匙串的操作才可以

    security unlock-keychain -p "password" ~/Library/Keychains/login.keychain-db  # "password"填mac的登录密码
    

    类似jenkins连接到mac打ios包、secureCrt连接到mac打ios包均会出现此类情况,用上述的方式应该可以解决

    相关文章

      网友评论

          本文标题:python库实战 - paramiko

          本文链接:https://www.haomeiwen.com/subject/fmlrohtx.html