背景:利用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()