基于Python实现的ssh兼sftp客户端
by:授客 QQ:1033553122
实现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'
import os
from paramiko.client import AutoAddPolicy
from paramiko.client import SSHClient
from otherTools import OtherTools
class MySSHClient:
def __init__(self):
self.ssh_client = SSHClient()
# 连接登录
def connect(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, '']
except Exception as e:
print('连接出错了%s' % e)
return [False, '%s' % e]
# 远程执行命令
def exec_command(self, command):
try:
print('正在执行命令:'+ command)
stdin, stdout, stderr = self.ssh_client.exec_command(command)
print('命令输出:')
print(stdout.read()) # 读取命令输出
return [True, tuple]
except Exception as e:
print('执行命:%s令出错' % command)
return [False,'%s' % e]
# 下载文件(非目录文件)
def download_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 not tail:
print('下载文件:%s 到本地:%s失败,本地文件名不能为空' % (remotepath, localpath))
return [False, '下载文件:%s 到本地:%s失败,本地文件名不能为空' % (remotepath, localpath)]
if not os.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, '']
except Exception as e:
print('下载文件:%s 到本地:%s 出错:%s' % (remotepath, localpath, e))
return [False, '下载文件:%s 到本地:%s 出错:%s' % (remotepath, localpath, e)]
# 上传文件(非目录文件)
def upload_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 not tail:
print('上传文件:%s 到远程:%s失败,本地文件名不能为空' % (localpath, remotepath))
return [False, '上传文件:%s 到远程:%s失败,本地文件名不能为空' % (localpath, remotepath)]
if not os.path.exists(head):
print( '上传文件:%s 到远程:%s失败,父路径不存在' % (localpath, remotepath, head))
return [False, '上传文件:%s 到远程:%s失败,父路径不存在' % (localpath, remotepath, head)]
if not (remotepath.startswith('/') or remotepath.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, '']
except Exception as e:
print('上传文件:%s 到远程:%s 出错:%s' % (localpath, remotepath, e))
return [False, '上传文件:%s 到远程:%s 出错:%s' % (localpath, remotepath, e)]
def close(self):
self.ssh_client.close()
Python 基于Python实现的ssh兼sftp客户端(下)