# coding=utf-8
"""
操作远程linux文件
"""
import paramiko
import os
import time
from pathlib import Path
from optparse import OptionParser
from concurrent.futures import ThreadPoolExecutor
def sftp_download_file(sftp, remote_file, local_file=None, local_dir=None):
"""
下载单个文件
:param sftp: sftp 连接
:param remote_file: 远程文件路径
:param local_file: 本地文件路径
:param local_dir: 本地文件目录路径
:return:
"""
if local_dir:
local_file = local_dir + '/' + os.path.basename(remote_file)
local_file = Path(local_file).as_posix()
remote_file = Path(remote_file).as_posix()
try:
sftp.file(remote_file)
except FileNotFoundError:
print("[ERROR]: 下载文件不存在...:信息如下", "远程目录路径:", remote_file)
return False
try:
sftp.get(remote_file, local_file) # 下载目录中文件
except IOError as e :
print("[ERROR]: 下载失败...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file, "ERROR:", e)
return False
print("[INFO]: 下载文件完成:信息如下", "远程文件路径:", remote_file, "本地文件路径:", local_file)
return True
def sftp_download_dir(sftp, local_dir, remote_dir):
"""
下载整个目录下的文件
:param sftp: sftp 连接
:param local_dir: 本地文件路径
:param remote_dir: 远程文件路径
:return:
"""
local_dir = Path(local_dir).as_posix()
remote_dir = Path(remote_dir).as_posix()
print("[INFO]: 开始下载文件目录...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)
if not os.path.exists(local_dir):
os.makedirs(local_dir)
try:
sftp.file(remote_dir)
except FileNotFoundError :
print("[ERROR]: 下载文件目录不存在...:信息如下", "远程目录路径:", remote_dir)
return False
if not sftp.listdir(remote_dir):
print("[INFO]: 下载文件目录为空...:信息如下", "远程目录路径:", remote_dir,)
return True
for file in sftp.listdir(remote_dir):
local = os.path.join(local_dir, file)
remote = remote_dir + '/' + file
remote = Path(remote).as_posix()
if 'd' == str(sftp.stat(remote))[0] : #d:目录文件,l:链接文件,b:设备文件,c:字符设备文件,p:管道文件
if not os.path.exists(local):
os.makedirs(local)
sftp_download_dir(sftp=sftp, local_dir=local, remote_dir=remote)
else: # 文件
sftp_download_file(sftp=sftp, local_file=local, remote_file=remote)
print("[INFO]: 下载文件目录完成...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)
return True
def sftp_upload_file(sftp, local_file, remote_file=None, remote_dir=None):
"""
上传文件
:param sftp:
:param local_file: 本地文件路径
:param remote_file: 远程文件路径
:param remote_dir: 远程文件目录路径
:return:
"""
if remote_dir:
remote_file = remote_dir + '/' + os.path.basename(local_file)
local_file = Path(local_file).as_posix()
remote_file = Path(remote_file).as_posix()
# print("[INFO]: 开始上传文件...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file)
if not os.path.exists(local_file):
print("[ERROR]: 上传本地文件不存在...:信息如下" "本地目录路径:", local_file)
return False
try:
sftp.put(local_file, remote_file)
except IOError as e:
print("[ERROR]: 上传失败...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file, "ERROR:", e)
return False
print("[INFO]: 上传文件完成...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file)
return True
def sftp_mkdir(sftp,remote_dir):
"""
创建文件目录
:param sftp:
:param remote_dir:远程文件路径
:return:
"""
remote_dir = Path(remote_dir).as_posix()
try:
sftp.file(remote_dir)
print("[WARING]: 创建文件目录已存在...:信息如下", "远程目录路径:", remote_dir)
return True
except FileNotFoundError:
try:
sftp.mkdir(remote_dir)
except IOError as e :
print("[ERROR]: 创建文件目录失败...:信息如下", "远程目录路径:", remote_dir, "ERROR:", e)
return False
print("[INFO]: 创建文件目录...:信息如下", "远程目录路径:", remote_dir)
return True
def sftp_upload_dir(sftp, local_dir, remote_dir):
"""
上传目录
:param sftp:
:param local_dir: 本地文件路径
:param remote_dir: 远程文件路径
:return:
"""
local_dir = Path(local_dir).as_posix()
remote_dir = Path(remote_dir).as_posix()
print("[INFO]: 开始上传文件目录...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)
if not Path(local_dir).is_dir():
print("[ERROR]: 上传文件目录不存在...:信息如下", "本地目录路径:", local_dir)
sftp_mkdir(sftp=sftp, remote_dir=remote_dir)
for root, dirs, files in os.walk(local_dir):
for dir in dirs:
local_path = os.path.join(root, dir)
dir_name = local_path.replace(local_dir, '')
remote_path = remote_dir + os.sep + dir_name
sftp_mkdir(sftp=sftp, remote_dir=remote_path)
for file in files:
local_file = os.path.join(root, file)
file_name = local_file.replace(local_dir, '')
remote_file = remote_dir + os.sep + file_name
sftp_upload_file(sftp=sftp, local_file =local_file, remote_file=remote_file)
print("[INFO]: 上传文件目录完成...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)
def ssh_conn(host, username='root', password='123456', port=22):
"""
获取 ssh 连接
:param host:
:param username:
:param password:
:param port:
:return:
"""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=username, password=password, port=port, allow_agent=False, look_for_keys=False)
return ssh
def format_time(times=time.time(), format='%Y%m%d%H%M%S'):
'''
格式化日期
:param times:
:return:
'''
return time.strftime(format, time.localtime(times))
def test_case():
ssh = ssh_conn(host='106.13.4.188', username='root', password='wang@3715', port=22)
sftp = ssh.open_sftp()
# 创建线程池 指定最大容纳数量
EXECUSTOR = ThreadPoolExecutor(max_workers=options.maxworkers)
# 下载文件目录
# local_dir = './data/' + format_time() # 本地文件
# remote_dir = '/home/wwl' # 远程文件或目录
# sftp_download_dir(sftp=sftp, local_dir=local_dir, remote_dir=remote_dir)
# 下载文件
# local_dir = './data/' + format_time() # 本地文件
# remote_file = '/home/log.log' # 远程文件或目录
# os.makedirs(local_dir)
# sftp_download_file(sftp=sftp, local_dir=local_dir, remote_file=remote_file)
# 上传 文件目录
# local_dir = r"D:\fuck\Java" # 本地文件
# remote_dir = '/home/wwl/TEMP' # 远程文件或目录
# sftp_upload_dir(sftp=sftp, local_dir=local_dir, remote_dir=remote_dir)
# 上传 文件文件
# local_file = r"D:\fuck\AI\Tensorflow.emmx" # 本地文件
# remote_dir = '/home/TEMP' # 远程文件或目录
# sftp_upload_file(sftp=sftp, local_file=local_file, remote_dir=remote_dir)
sftp.close()
ssh.close()
def main(options):
ssh = ssh_conn(host=options.ip, username=options.username, password=options.password, port=options.port)
sftp = ssh.open_sftp()
if options.isupload :#上传
if options.localdir :
if options.remotedir:
sftp_upload_dir(sftp=sftp, local_dir=options.localdir, remote_dir=options.remotedir)
else:
print("[ERROR]:","The upload directory must correspond to the remote directory")
elif options.localfile:
sftp_upload_file(sftp=sftp, local_file=options.localfile, remote_file=options.remotefile, remote_dir=options.remotedir)
else:
print("[ERROR]:", "The local file path is not configured")
else: # 下载
if options.remotedir :
if options.localdir :
sftp_download_dir(sftp=sftp, local_dir=options.localdir, remote_dir=options.remotedir)
else:
print("[ERROR]:", "The download remote server directory must exist in the corresponding local directory")
elif options.remotefile:
sftp_download_file(sftp=sftp, remote_file=options.remotefile, local_file=options.localfile, local_dir=options.localdir)
else:
print("[ERROR]:", "The remote servers file path is not configured")
sftp.close()
ssh.close()
if __name__ == '__main__':
usage = '[*] Usage : such as: ' + os.path.basename(__file__) + \
' -i 127.0.0.1 -u root -p 123456 -T true -d ./data -r /home/temp'
parser = OptionParser(usage)
parser.add_option('-i', '--ip', dest='ip', type='string', help='specify remote servers ip')
parser.add_option('-u', '--user', dest='username', type='string', help='specify remote servers username')
parser.add_option('-p', '--password', dest='password', type='string', help='specify remote servers clientpassword')
parser.add_option('-P', '--port', dest='port', type='int', help='specify remote servers port,default 22', default=22)
parser.add_option('-T', '--isupload', dest='isupload', type='string', help='Whether to upload files, default False', default=False)
parser.add_option('-d', '--localdir', dest='localdir', type='string', help='local file directory path: either-or localfile')
parser.add_option('-f', '--localfile', dest='localfile', type='string', help='local file path')
parser.add_option('-r', '--remotedir', dest='remotedir', type='string', help='remote servers file directory path : either-or remotefile')
parser.add_option('-t', '--remotefile', dest='remotefile', type='string', help='remote servers file path')
(options, args) = parser.parse_args()
#远程服务SSH登录 参数
if (options.ip == None) | (options.username == None) | (options.password == None):
print("[ERROR]:", parser.usage)
exit(1)
#传输文件路径 参数
if (options.localdir == None and options.localfile == None) | (options.remotedir == None and options.remotefile == None):
print("[ERROR]:", parser.usage)
exit(1)
#主函数
main(options)
exit(0)
操作远程linux文件
最新推荐文章于 2024-08-25 17:52:22 发布