python库实战 - paramiko

2020-05-18  本文已影响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包均会出现此类情况,用上述的方式应该可以解决

上一篇下一篇

猜你喜欢

热点阅读