Python Paramiko 目录遍历 SFTP
Python Paramiko directory walk over SFTP
如何在另一台计算机上通过 SSH os.walk()
?问题是 os.walk()
在本地机器上执行,我想通过 ssh 连接到另一台主机,遍历目录并为其中的每个文件生成 MD5 哈希值。
到目前为止我写的看起来像这样(在代码下方)但它不起作用。任何帮助将不胜感激。
try:
hash_array = []
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('sunbeam', port=22, username='xxxx', password='filmlight')
spinner.start()
for root, dirs, files in os.walk(_path):
for file in files:
file_path = os.path.join(os.path.abspath(root), file)
# generate hash code for file
hash_array.append(genMD5hash(file_path))
file_nb += 1
spinner.stop()
spinner.ok('Finished.')
return hash_array
except Exception as e:
print(e)
return None
finally:
ssh.close()
要使用标准文件访问接口 SFTP 使用 Paramiko 递归列出目录,您需要使用 SFTPClient.listdir_attr
:
实现递归函数
from stat import S_ISDIR, S_ISREG
def listdir_r(sftp, remotedir):
for entry in sftp.listdir_attr(remotedir):
remotepath = remotedir + "/" + entry.filename
mode = entry.st_mode
if S_ISDIR(mode):
listdir_r(sftp, remotepath)
elif S_ISREG(mode):
print(remotepath)
基于 。
或者,pysftp implements an os.walk
equivalent: Connection.walktree
。
尽管使用 SFTP 协议获取远程文件的 MD5 会遇到麻烦。
虽然 Paramiko 通过其 SFTPFile.check
支持它,但大多数 SFTP 服务器(尤其是最广泛的 SFTP/SSH 服务器 – OpenSSH)不支持。
参见:
How to check if Paramiko successfully uploaded a file to an SFTP server? 和
How to perform checksums during a SFTP file transfer for data integrity?
所以你很可能不得不求助于使用 shell md5sum
命令(如果你有 shell 访问权限的话)。一旦你不得不使用 shell,请考虑使用 shell 列出文件,因为这比通过 SFTP 快得多。
参见 md5 all files in a directory tree。
强制性警告:请勿使用 AutoAddPolicy
– 您正在失去针对 MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".
的保护
基于,这里是一个不需要递归的版本和returns一个路径列表,而不是使用print
命令。
from stat import S_ISDIR, S_ISREG
from collections import deque
def listdir_r(sftp, remotedir):
dirs_to_explore = deque([remotedir])
list_of_files = deque([])
while len(dirs_to_explore) > 0:
current_dir = dirs_to_explore.popleft()
for entry in sftp.listdir_attr(current_dir):
current_fileordir = current_dir + "/" + entry.filename
if S_ISDIR(entry.st_mode):
dirs_to_explore.append(current_fileordir)
elif S_ISREG(entry.st_mode):
list_of_files.append(current_fileordir)
return list(list_of_files)
如何在另一台计算机上通过 SSH os.walk()
?问题是 os.walk()
在本地机器上执行,我想通过 ssh 连接到另一台主机,遍历目录并为其中的每个文件生成 MD5 哈希值。
到目前为止我写的看起来像这样(在代码下方)但它不起作用。任何帮助将不胜感激。
try:
hash_array = []
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('sunbeam', port=22, username='xxxx', password='filmlight')
spinner.start()
for root, dirs, files in os.walk(_path):
for file in files:
file_path = os.path.join(os.path.abspath(root), file)
# generate hash code for file
hash_array.append(genMD5hash(file_path))
file_nb += 1
spinner.stop()
spinner.ok('Finished.')
return hash_array
except Exception as e:
print(e)
return None
finally:
ssh.close()
要使用标准文件访问接口 SFTP 使用 Paramiko 递归列出目录,您需要使用 SFTPClient.listdir_attr
:
from stat import S_ISDIR, S_ISREG
def listdir_r(sftp, remotedir):
for entry in sftp.listdir_attr(remotedir):
remotepath = remotedir + "/" + entry.filename
mode = entry.st_mode
if S_ISDIR(mode):
listdir_r(sftp, remotepath)
elif S_ISREG(mode):
print(remotepath)
基于
或者,pysftp implements an os.walk
equivalent: Connection.walktree
。
尽管使用 SFTP 协议获取远程文件的 MD5 会遇到麻烦。
虽然 Paramiko 通过其 SFTPFile.check
支持它,但大多数 SFTP 服务器(尤其是最广泛的 SFTP/SSH 服务器 – OpenSSH)不支持。
参见:
How to check if Paramiko successfully uploaded a file to an SFTP server? 和
How to perform checksums during a SFTP file transfer for data integrity?
所以你很可能不得不求助于使用 shell md5sum
命令(如果你有 shell 访问权限的话)。一旦你不得不使用 shell,请考虑使用 shell 列出文件,因为这比通过 SFTP 快得多。
参见 md5 all files in a directory tree。
强制性警告:请勿使用 AutoAddPolicy
– 您正在失去针对 MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".
基于print
命令。
from stat import S_ISDIR, S_ISREG
from collections import deque
def listdir_r(sftp, remotedir):
dirs_to_explore = deque([remotedir])
list_of_files = deque([])
while len(dirs_to_explore) > 0:
current_dir = dirs_to_explore.popleft()
for entry in sftp.listdir_attr(current_dir):
current_fileordir = current_dir + "/" + entry.filename
if S_ISDIR(entry.st_mode):
dirs_to_explore.append(current_fileordir)
elif S_ISREG(entry.st_mode):
list_of_files.append(current_fileordir)
return list(list_of_files)