python 3.4 telnetlib 与 paramiko实践

背景:利用python 的telnetlib 和paramiko库,可以实现自动化 telnet 交互,SSH交互,并可以实现文件及目录的批量上传与下载。

import re
import telnetlib
import paramiko,getopt,sys,time,datetime,os
from IPy import IP

函数及用法总结

paramiko, 实现远程控制linux进行SSH交互

def creatSShConnectOb(ip_remote, port_remote, username, password):
    print('---------- start to create SSH object')
    print('Remote SSH Info:\n\'ip:%s  port:%d  username:%s  password:%s\'\n' %(ip_remote, port_remote, username, password))
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect(ip_remote, port_remote, username=username, password=password, timeout=60) #  timeout protection
        return ssh
    except:
        print('Warning:\nFist connect the remote linux failed, now will retry!')
        ssh.connect(ip_remote, port_remote, username=username, password=password, timeout=60) #  timeout re-try
        print('Error:\nAttempt to connect remote linux server failed!!! Please check the IP / port/ account / password.')
    else:
        print('Info:\nConnect remote linux server success.')
    
def execSShCmd(ssh, sshCmd):
    stdin, stdout, stderr = ssh.exec_command(sshCmd,timeout = 20)
    print('Exec sshCmd:\n\'' + sshCmd + '\'')
    print('Exec Result:')
    ssh.exec_command(sshCmd)
    print(stdout.readlines())
    time.sleep(2)   

if __name__ == '__main__':
    ssh = creatSShConnectOb(ip,port,username,password)
    sshCmd = 'ls -R ' + remoteDir
    execSShCmd(ssh, sshCmd)
    sshCmd = 'unzip -o -d ' + remoteDir + 'temp' + os.path.join(remoteDir, filename)
    execSShCmd(ssh, sshCmd)
    print('SSH finish !!!')
    ssh.close()

paramiko,利用其中的sftp listdir方法,递归遍历远程服务器所有子目录及其文件,并找到目标文件(包含:feature = 'string' 的文件)下载。  由于sftp的方法太少了,不支持linux 中的‘*’通配符查找,所以只能使用递归遍历的方法了。找遍网上都没有现成的方法,所以自己写了一个:

def serachAndDownloadFeatureFile(rootPath, feature, ip_remote, port_remote, username, password):
    try:
        t = paramiko.Transport((ip_remote,port_remote))
        t.connect(username=username,password=password)
        sftp = paramiko.SFTPClient.from_transport(t)
        files = sftp.listdir(rootPath)#获取到根目录下的所有目录名称+文件名字
        #print('------------')
        #print('current path:%s' % rootPath)
        #print(files)

        for name in files:
            path = os.path.join(rootPath, name)
            path = path.replace('\\','/')
            attribute = str(sftp.stat(path))
            if re.search(feature,path):
                print('\nInfo: File matched !!!')
                local_file_path = os.path.join(localDir, name)
                local_file_path = local_file_path.replace('\\','/')
                print('Downloading file from remote %s to local %s'%(path,local_file_path))
                sftp.get(path,local_file_path)
            else:
                if attribute[0] == 'd':#是文件夹, 继续遍历
                    print('Start to search documents:%s'% path)
                    serachAndDownloadFeatureFile(path, feature, ip_remote, port_remote, username, password)
            
        t.close()
    except Exception as err:
           print(err)

上传的是本地的文件,故可以使用os库遍历本地目录,子目录及其文件来上传。

#上传整个目录(含全部子目录+文件)
def uploadDocuments(local_dir, remote_dir, ip_remote, port_remote, username, password):
    try:
        tran=paramiko.Transport((ip_remote,port_remote))
        tran.connect(username=username,password=password)
        sftp=paramiko.SFTPClient.from_transport(tran)
        print ('===========upload file start %s ' % (datetime.datetime.now()))
        for root,dirs,files in os.walk(local_dir):
            for fileName in files:
                local_file = os.path.join(root,fileName)
                #print("local_file:" + local_file)
                temp = local_file.replace(local_dir,'')
                temp = temp.replace('\\','/')# 保护
                remote_file = os.path.join(remote_dir,temp)
                #print("remote_file:" + remote_file)
                local_file = local_file.replace('\\','/')# 保护
                remote_file = remote_file.replace('\\','/')# 保护
                try:
                    sftp.put(local_file,remote_file)
                except:
                    sftp.mkdir(os.path.split(remote_file)[0])
                    sftp.put(local_file,remote_file)
                print("upload %s to remote %s" % (local_file,remote_file))
            for dirName in dirs:
                local_path = os.path.join(root,dirName)
                #print("local_path:" + local_path)
                temp = local_path.replace(local_dir,'')
                temp = temp.replace('\\','/')
                remote_path = os.path.join(remote_dir,temp)
                #print("remote_path:" + remote_path)
                local_path = local_path.replace('\\','/')
                remote_path = remote_path.replace('\\','/')
                try:
                    sftp.mkdir(remote_path)
                    #print ("mkdir path %s" % remote_path)
                except:
                    print("mkdir failed : %s" % remote_path)
        print ('===========upload all file success %s ' % datetime.datetime.now())
        tran.close()
    except:
        print ('===========upload file failed %s ' % datetime.datetime.now())

上传/下载单个文件:

#上传单个文件  using: sendFile(r'C:/v7cat/unzip-6.0-5.el6.x86_64.rpm', r'/root/unzip-6.0-5.el6.x86_64.rpm')
def sendFile(localSourceFile, remoteFile, ip_remote, port_remote, username, password):
    tran = paramiko.Transport(ip_remote,port_remote)
    tran.connect(username=username, password=password)
    sftp = paramiko.SFTPClient.from_transport(tran)
    print('Sending %s to remote linux[%s]' %(localSourceFile, remoteFile))
    sftp.put(localSourceFile,remoteFile)
    time.sleep(5)

#下载单个文件  using: sendFile(r'C:/v7cat/unzip-6.0-5.el6.x86_64.rpm', r'/root/unzip-6.0-5.el6.x86_64.rpm')
def getFile(localSourceFile, remoteFile, ip_remote, port_remote, username, password):
    tran = paramiko.Transport(ip_remote,port_remote)
    tran.connect(username=username, password=password)
    sftp = paramiko.SFTPClient.from_transport(tran)
    #if remote_dir[-1] == '/'
    #    remote_dir = remote_dir[0:-1]
    print('Downloading %s to remote linux[%s]' %(localSourceFile, remoteFile))
    sftp.get(remoteFile,localSourceFile)
    time.sleep(5)

telnetlib库,可以实现和telnet服务器的交互:

def creatTelnetConnectOb():
    print('---------- start to create telnet object')
    print('Remote telnet Info:\n\'_ip:%s  _port:%d  _username:%s  _password:%s\'\n' %(_ip, _port, _username, _password))
    tn = telnetlib.Telnet()
    # tn.set_debuglevel(1) # 关闭telnetlib的调试打印
    try:
        tn.open(_ip, _port, timeout = 20)
        return tn
    except:
        print("telnet  failed, please check the  login info!!!")

def execTelnetCmd(tn, sshCmd):
    print('--telnet sshCmd:%s\n' % sshCmd)
    tn.write(sshCmd + b'\n')
    #print(tn.read_all().decode('ascii'))

def autoTelnet():
    tn = creatTelnetConnectOb()
    if tn.read_until(b'login username:', timeout = 20):
        print('---------- enter username')
        execTelnetCmd(tn, username)
        #print(tn.read_all().decode('ascii'))
    if tn.read_until(b'password:', timeout = 20):
        print('---------- enter password')
        execTelnetCmd(tn, _password)
    print('---------- exec telnet cmd')
    if tn.read_until(finish, 20):
        sshCmd = b'LOAD \"version\"'
        execTelnetCmd(tn, sshCmd)
        time.sleep(300)
        #print(tn.read_all().decode('ascii'))
        command_result = tn.read_very_eager()

    if 'vresion have been successfully loaded' not in str(command_result):
        print('Warning: vresion load failed, please check the environment ~!\n')
        print('exec result:\n\n %s' % str(command_result))
        sys.exit(1)
    else:
        print('Info: vresion have been successfully loaded ~!\n')

    print('Telnet finish !!!\n')
    tn.close()

猜你喜欢

转载自blog.csdn.net/qqyuanhao163/article/details/88891300
3.4
今日推荐