使用 SFTP 和 Paramiko 获取递归文件夹 Python
Get Recursive folder using SFTP and Paramiko Python
尝试实现一个 python 脚本并将获取递归文件夹从远程机器放入本地机器,此代码适用于复制:放置文件夹和获取文件夹,现在我想创建移动,想法是要在传输后删除文件,我添加行 sftp.remove() 并在 post 的末尾获取错误堆栈任何线索家伙?
import paramiko
import os
from stat import S_ISDIR, S_ISREG
class MySFTPClient(paramiko.SFTPClient):
def put_dir(self, source, target):
''' Uploads the contents of the source directory to the target path. The
target directory needs to exists. All subdirectories in source are
created under target.
'''
for item in os.listdir(source):
if os.path.isfile(os.path.join(source, item)):
self.put(os.path.join(source, item), '%s/%s' % (target, item))
else:
self.mkdir('%s/%s' % (target, item), ignore_existing=True)
self.put_dir(os.path.join(source, item), '%s/%s' % (target, item))
def mkdir(self, path, mode=511, ignore_existing=False):
''' Augments mkdir by adding an option to not fail if the folder exists '''
try:
super(MySFTPClient, self).mkdir(path, mode)
except IOError:
if ignore_existing:
pass
else:
raise
def sftp_get_recursive(path, dest, sftp):
item_list = sftp.listdir_attr(path)
dest = str(dest)
if not os.path.isdir(dest):
os.makedirs(dest, exist_ok=True)
for item in item_list:
mode = item.st_mode
if S_ISDIR(mode):
sftp_get_recursive(path + "/" + item.filename, dest + "/" + item.filename, sftp)
else:
sftp.get(path + "/" + item.filename, dest + "/" + item.filename)
print("Removing file :",item.filename)
sftp.remove(dest + "/" + item.filename)
Solved by changing sftp.remove(dest + "/" + item.filename) to sftp.remove(path + "/" + item.filename)
transport = paramiko.Transport(('172.31.11.233', 22))
transport.connect(username='$(ops_unv_cred_user_018f3e16e789465bb5110a90837ce03f)', password='$(ops_unv_cred_pwd_018f3e16e789465bb5110a90837ce03f)')
if 1==1:
sftp = paramiko.SFTPClient.from_transport(transport)
if 0==1:
sftp.get('/home/karim/EDV','/home/karim/israel')
print("copied successfully!")
else:
sftp_get_recursive('/home/karim/EDV', '/home/karim/israel', sftp)
print("copied successfully!")
if 1==1:
print("Listing all files in remote machine where path is => /home/karim/EDV :" )
print(sftp.listdir('/home/karim/EDV'))
if 1==1:
print("Listing all files in remote machine where path is => /home/karim/EDV :" )
print(sftp.listdir('/home/karim/EDV'))
else:
sftp = MySFTPClient.from_transport(transport)
if 0==1:
sftp.put('/home/karim/israel','/home/karim/EDV')
print("copied successfully!")
else:
sftp.mkdir('/home/karim/EDV', ignore_existing=True)
sftp.put_dir('/home/karim/israel','/home/karim/EDV')
print("copied successfully!")
if 1==1:
print("Listing all files in remote machine where path is => /home/karim/EDV :" )
print(sftp.listdir('/home/karim/EDV'))
sftp.close()
Traceback (most recent call last): File "/home/karim/.56ee3cce-0616-4070-bfa5-b5a0f346b2c7.sh", line 64, in <module>
sftp_get_recursive('/home/karim/EDV', '/home/karim/israel', sftp) File "/home/karim/.56ee3cce-0616-4070-bfa5-b5a0f346b2c7.sh", line 50, in sftp_get_recursive
sftp_get_recursive(path + "/" + item.filename, dest + "/" + item.filename, sftp) File "/home/karim/.56ee3cce-0616-4070-bfa5-b5a0f346b2c7.sh", line 54, in sftp_get_recursive
sftp.remove(dest + "/" + item.filename) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 398, in remove
self._request(CMD_REMOVE, path) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 813, in _request
return self._read_response(num) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 865, in _read_response
self._convert_status(msg) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 894, in _convert_status
raise IOError(errno.ENOENT, text) FileNotFoundError: [Errno 2] No such file
根据您的评论,target
似乎是一个远程路径,尽管它应该是“源”,因为您正在下载。并且您正在使用本地 API 的远程路径,例如 os.listdir
。那行不通,您应该使用 SFTPClient.listdir_attr
.
有关有效递归下载的示例,请参阅:
Recursive directory download with Paramiko?
尝试实现一个 python 脚本并将获取递归文件夹从远程机器放入本地机器,此代码适用于复制:放置文件夹和获取文件夹,现在我想创建移动,想法是要在传输后删除文件,我添加行 sftp.remove() 并在 post 的末尾获取错误堆栈任何线索家伙?
import paramiko
import os
from stat import S_ISDIR, S_ISREG
class MySFTPClient(paramiko.SFTPClient):
def put_dir(self, source, target):
''' Uploads the contents of the source directory to the target path. The
target directory needs to exists. All subdirectories in source are
created under target.
'''
for item in os.listdir(source):
if os.path.isfile(os.path.join(source, item)):
self.put(os.path.join(source, item), '%s/%s' % (target, item))
else:
self.mkdir('%s/%s' % (target, item), ignore_existing=True)
self.put_dir(os.path.join(source, item), '%s/%s' % (target, item))
def mkdir(self, path, mode=511, ignore_existing=False):
''' Augments mkdir by adding an option to not fail if the folder exists '''
try:
super(MySFTPClient, self).mkdir(path, mode)
except IOError:
if ignore_existing:
pass
else:
raise
def sftp_get_recursive(path, dest, sftp):
item_list = sftp.listdir_attr(path)
dest = str(dest)
if not os.path.isdir(dest):
os.makedirs(dest, exist_ok=True)
for item in item_list:
mode = item.st_mode
if S_ISDIR(mode):
sftp_get_recursive(path + "/" + item.filename, dest + "/" + item.filename, sftp)
else:
sftp.get(path + "/" + item.filename, dest + "/" + item.filename)
print("Removing file :",item.filename)
sftp.remove(dest + "/" + item.filename)
Solved by changing sftp.remove(dest + "/" + item.filename) to sftp.remove(path + "/" + item.filename)
transport = paramiko.Transport(('172.31.11.233', 22))
transport.connect(username='$(ops_unv_cred_user_018f3e16e789465bb5110a90837ce03f)', password='$(ops_unv_cred_pwd_018f3e16e789465bb5110a90837ce03f)')
if 1==1:
sftp = paramiko.SFTPClient.from_transport(transport)
if 0==1:
sftp.get('/home/karim/EDV','/home/karim/israel')
print("copied successfully!")
else:
sftp_get_recursive('/home/karim/EDV', '/home/karim/israel', sftp)
print("copied successfully!")
if 1==1:
print("Listing all files in remote machine where path is => /home/karim/EDV :" )
print(sftp.listdir('/home/karim/EDV'))
if 1==1:
print("Listing all files in remote machine where path is => /home/karim/EDV :" )
print(sftp.listdir('/home/karim/EDV'))
else:
sftp = MySFTPClient.from_transport(transport)
if 0==1:
sftp.put('/home/karim/israel','/home/karim/EDV')
print("copied successfully!")
else:
sftp.mkdir('/home/karim/EDV', ignore_existing=True)
sftp.put_dir('/home/karim/israel','/home/karim/EDV')
print("copied successfully!")
if 1==1:
print("Listing all files in remote machine where path is => /home/karim/EDV :" )
print(sftp.listdir('/home/karim/EDV'))
sftp.close()
Traceback (most recent call last): File "/home/karim/.56ee3cce-0616-4070-bfa5-b5a0f346b2c7.sh", line 64, in <module>
sftp_get_recursive('/home/karim/EDV', '/home/karim/israel', sftp) File "/home/karim/.56ee3cce-0616-4070-bfa5-b5a0f346b2c7.sh", line 50, in sftp_get_recursive
sftp_get_recursive(path + "/" + item.filename, dest + "/" + item.filename, sftp) File "/home/karim/.56ee3cce-0616-4070-bfa5-b5a0f346b2c7.sh", line 54, in sftp_get_recursive
sftp.remove(dest + "/" + item.filename) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 398, in remove
self._request(CMD_REMOVE, path) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 813, in _request
return self._read_response(num) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 865, in _read_response
self._convert_status(msg) File "/opt/universal/python/lib/python3.7/site-packages/paramiko/sftp_client.py", line 894, in _convert_status
raise IOError(errno.ENOENT, text) FileNotFoundError: [Errno 2] No such file
根据您的评论,target
似乎是一个远程路径,尽管它应该是“源”,因为您正在下载。并且您正在使用本地 API 的远程路径,例如 os.listdir
。那行不通,您应该使用 SFTPClient.listdir_attr
.
有关有效递归下载的示例,请参阅:
Recursive directory download with Paramiko?