首页 > 解决方案 > 使用 python 从 samba 复制目录/子目录中的所有文件

问题描述

我正在尝试使用 Python 脚本从 Samba (SMB) 连接复制整个目录或目录中的所有文件及其子目录。我知道如何使用以下方法获取单个文件:

conn = SMBConnection('server',
                     'password',
                     'IP',
                     'share',
                     use_ntlm_v2 = True)
assert conn.connect('IP', 139)

x = 'test.txt'

with open(x, 'wb') as fp:
    conn.retrieveFile('shared', '/EC/test/Pytest/Confocal/test.txt', fp)

但我想实现类似的东西:

root = "/home/to/directory/"
path = os.path.join(root, "source")
destination = "/home/to/target/directory/"

for path, subdirs, files in os.walk(root):
    for name in files:
        print (os.path.join(path, name))
        if name.endswith(".nimp"):
            shutil.move(os.path.join(path, name), destination)

获取具有特定类型(即.nimp)的子目录中的所有文件。此代码在使用本地目录时有效,但我无法将其实现到 SMB 连接。根据文档,没有复制整个文件夹的命令。我还想将文件动态保存为 SMB 连接中的当前名称。有什么建议么?

或者,我正在考虑复制整个文件夹,然后使用第二段代码复制所有文件,然后删除复制的文件夹。这也可能吗?

此外,该网站上没有任何帖子可以解决我的具体问题。

标签: pythonubuntuubuntu-16.04sambasmb

解决方案


这是一个可能对您有所帮助的示例。

我省略了一些膨胀,这是我具体上下文中的一个例子,你应该关注copyDir功能。这就是使用 samba 递归遍历目录并将其复制到本地计算机的功能(也就是整个目录树将被复制,现有文件将被覆盖)。

#!/usr/bin/env python3

import os
import sys
import json
import getpass
from smb.SMBConnection import SMBConnection
from subprocess import Popen, PIPE

gameName = None
shareType = None
packToApply = None
basePath = None

def readUsername():
    return ''

def readPw():
    return ''

def copyPack(conn):
    os.chdir(os.path.join(HOME_DIR, config_data.get('pathToEngineFromHome', ''), f"engine/games/{gameName}"))

    for e in conn.listPath(SHARE_NAME, basePath):
        if e.isDirectory and e.filename not in ['.', '..']:
            copyDir(conn, e.filename)

def copyDir(conn, dirName):
    dir = conn.listPath(SHARE_NAME, os.path.join(basePath, dirName))
    for e in dir:
        if not e.isDirectory:
            filepath = os.path.join(dirName, e.filename)
            with open(filepath, 'wb') as f:
                conn.retrieveFile(SHARE_NAME, os.path.join(basePath, filepath), f)
        elif e.filename not in ['.', '..']:
            copyDir(conn, os.path.join(dirName, e.filename))

if __name__ == "__main__":
    if gameName and type:
        basePath = f'{gameName}/INT/{shareType}/{packToApply}/EXPORTS'

        username = readUsername()
        pw = readPw()
        
        # create samba connection
        conn = SMBConnection(username, pw, 'AIAIAI', 'SERVER', use_ntlm_v2=True)
        assert conn.connect(SHARES_SERVER)

        copyPack(conn)

        conn.close()

推荐阅读