基于Python实现的ssh兼sftp客户端
实现ssh客户端兼ftp客户端:实现远程连接,执行linux命令,上传下载文件
Win7 64位
Python 3.3.4
paramiko 1.15.2
下载地址:
https://pypi.python.org/pypi/paramiko/1.15.2
https://pan.baidu.com/s/1i4SJ1CL
cryptography-1.0-cp34-none-win_amd64.whl
(如果paramiko可以正常安装完,则不需要安装该类库)
下载地址:
https://pypi.python.org/pypi/cryptography/1.0
https://pan.baidu.com/s/1jIRBJvg
安装好后,找到nt.py(本例中路径为:
Lib\site-packages\pycrypto-2.6.1-py3.4-win-amd64.egg\Crypto\Random\OSRNG\nt.py),修改
import winrandom
为
from Crypto.Random.OSRNG import winrandom
如下
#import winrandom
from Crypto.Random.OSRNG import winrandom
以解决ImportError: No module named 'winrandom'错误
VS2010
因操作系统而异,可能需要安装VS2010,以解决包依赖问题
mysshclient.py
#!/usr/bin/env/ python
# -*- coding:utf-8 -*-
__author__ ='shouke'
importos
fromparamiko.clientimportAutoAddPolicy
fromparamiko.clientimportSSHClient
fromotherToolsimportOtherTools
classMySSHClient:
def__init__(self):
self.ssh_client = SSHClient()
# 连接登录
defconnect(self, hostname, port, username, password):
try:
print('正在远程连接主机:%s'% hostname)
self.ssh_client.set_missing_host_key_policy(AutoAddPolicy())
self.ssh_client.connect(hostname=hostname,port=port,username=username,password=password)
return[True,'']
exceptExceptionase:
print('连接出错了%s'% e)
return[False,'%s'% e]
# 远程执行命令
defexec_command(self, command):
try:
print('正在执行命令:'+ command)
stdin, stdout, stderr =self.ssh_client.exec_command(command)
print('命令输出:')
print(stdout.read())# 读取命令输出
return[True,tuple]
exceptExceptionase:
print('执行命:%s令出错'% command)
return[False,'%s'% e]
# 下载文件(非目录文件)
defdownload_file(self, remotepath, localpath):
try:
localpath = os.path.abspath(localpath)
localpath = localpath.replace('\t','/t').replace('\n','/n').replace('\r','/r').replace('\b','/b')# 转换特殊字符
localpath = localpath.replace('\f','/f')
print('转换后的本地目标路径为:%s'% localpath)
head, tail = os.path.split(localpath)
if nottail:
print('下载文件:%s到本地:%s失败,本地文件名不能为空'% (remotepath, localpath))
return[False,'下载文件:%s到本地:%s失败,本地文件名不能为空'% (remotepath, localpath)]
if notos.path.exists(head):
print('本地路径:%s不存在,正在创建目录'% head)
OtherTools().mkdirs_once_many(head)
sftp_client =self.ssh_client.open_sftp()
print('正在下载远程文件:%s到本地:%s'% (remotepath, localpath))
sftp_client.get(remotepath, localpath)
sftp_client.close()
return[True,'']
exceptExceptionase:
print('下载文件:%s到本地:%s出错:%s'% (remotepath, localpath, e))
return[False,'下载文件:%s到本地:%s出错:%s'% (remotepath, localpath, e)]
# 上传文件(非目录文件)
defupload_file(self, localpath, remotepath):
try:
localpath = localpath.rstrip('\\').rstrip('/')
localpath = localpath.replace('\t','/t').replace('\n','/n').replace('\r','/r').replace('\b','/b')# 转换特殊字符
localpath = localpath.replace('\f','/f')
localpath = os.path.abspath(localpath)
print('转换后的本地文件路径为:%s'% localpath)
remotepath = remotepath.rstrip('\\').rstrip('/')
head, tail = os.path.split(localpath)
if nottail:
print('上传文件:%s到远程:%s失败,本地文件名不能为空'% (localpath, remotepath))
return[False,'上传文件:%s到远程:%s失败,本地文件名不能为空'% (localpath, remotepath)]
if notos.path.exists(head):
print('上传文件:%s到远程:%s失败,父路径不存在'% (localpath, remotepath, head))
return[False,'上传文件:%s到远程:%s失败,父路径不存在'% (localpath, remotepath, head)]
if not(remotepath.startswith('/')orremotepath.startswith('.')):
print('上传文件:%s到远程:%s失败,远程路径填写不规范%s'% (localpath, remotepath,remotepath))
return[False,'上传文件:%s到远程:%s失败,远程路径填写不规范%s'% (localpath, remotepath,remotepath)]
sftp_client =self.ssh_client.open_sftp()
head, tail = os.path.split(remotepath)
head = sftp_client.normalize(head)# 规范化路径
remotepath = head +'/'+ tail
print('规范化后的远程目标路径:', remotepath)
print('正在上传文件:%s到远程:%s'% (localpath, remotepath))
sftp_client.put(localpath, remotepath)
sftp_client.close()
return[True,'']
exceptExceptionase:
print('上传文件:%s到远程:%s出错:%s'% (localpath, remotepath, e))
return[False,'上传文件:%s到远程:%s出错:%s'% (localpath, remotepath, e)]
defclose(self):
self.ssh_client.close()