(一)Samba服务器的部署

本文使用wsl来进行Linux平台(Debian或者Ubuntu)的Samba服务器部署,具体的操作流程可以参考:玩转WSL-用Samba服务替代Win10原生的文件共享。流程很详尽,给大佬比个心。
下面主要说下部署过程中遇到的一些不太常见的坑点:

  1. 在给Samba服务设置用户还是启动Samba服务(记不清了)这一步报错了,后来忘记是在StackOverflow还是Github上的讨论中找到了答案:Samba服务不支持在wsl上部署,只能升级到wsl2重头来过!
  2. 参考win10 启用wsl2 并设置wsl2子系统为Windows Terminal终端的默认启动项以及启动快捷键可以很快地将wsl升级到wsl2,这时候启动Ubuntu发现一直安装失败,最后在win10 WSL2问题解决WslRegisterDistribution failed with error: 0x800701bc发现原来是我升级的过程中漏掉了安装WSL2 Linux 内核更新包
  3. 还有一种情况是在wsl启动Samba服务之后,在Windows命令行执行netstat -a | findstr LISTENING发现并没有重新监听到139和445端口,而且在Windows的资源管理器输入//127.0.0.1也连接不上Samba服务器。这时候不要心急,可能只是服务起的比较慢,耐心试几次就好(本人亲身经历T_T)。

(二)共享文件夹的使用

  • 可以直接使用Windows的资源管理器来连接Samba服务器实现文件共享。当然,我辛辛苦苦搭一个Samba服务器也不是为了这样用的啦。
  • 利用Python的pysmb库就可以来实现一个简单的客户端来连接Samba服务器进行文件共享操作了,我的代码是基于Python——操作smb文件服务器(上传和下载)的基础上进行调整的,基本上能够涵盖所需要的文件操作:
    # -*- coding:utf-8 -*-
    import os
    from smb.SMBConnection import SMBConnection, OperationFailure
    
    class SMBClient(object):
        status = False
        samba = None
    
        def __init__(self, user_name, passwd, ip, port=445):
            self.user_name = user_name
            self.passwd = passwd
            self.ip = ip
            self.port = port
    
        def connect(self):
            try:
                self.samba = SMBConnection(self.user_name, self.passwd, '', '', use_ntlm_v2=True)
                self.samba.connect(self.ip, self.port)
                self.status = self.samba.auth_result
            except:
                self.samba.close()
    
        def disconnect(self):
            if self.status:
                self.samba.close()
    
        def download(self, filenames, local_dir, service_name, smb_dir=''):
            """
            下载文件
            :param filenames: 文件路径(列表)
            :param local_dir: 本地目录
            :param service_name: 服务名(samba服务器中/etc/samba/smb.conf的[]里的名称)
            :param smb_dir: samba服务目录下的文件目录,如果目录下文件路径和filenames完全一致则保留默认值即可
            :return:
            """
            if type(filenames) is not list:
                filenames = [filenames]
            for filename in filenames:
                with open(os.path.join(local_dir, filename), 'w') as f:
                    self.samba.retrieveFile(service_name, os.path.join(smb_dir, filename), f)
    
        def upload(self, filenames, local_dir, service_name, smb_dir=''):
            """
            上传文件
            :param filenames: 文件路径(列表)
            :param local_dir: 本地目录
            :param service_name: 服务名(samba服务器中/etc/samba/smb.conf的[]里的名称)
            :param smb_dir: samba服务目录下的文件目录,如果目录下文件路径和filenames完全一致则保留默认值即可
            """
            if type(filenames) is not list:
                filenames = [filenames]
            for filename in filenames:
                with open(os.path.join(local_dir, filename), 'r') as f:
                    self.samba.storeFile(service_name, os.path.join(smb_dir, filename), f)
    
        def createDir(self, service_name, path):
            """
            创建文件夹
            :param service_name: 服务名(samba服务器中/etc/samba/smb.conf的[]里的名称)
            :param path: 目录路径
            """
            try:
                self.samba.createDirectory(service_name, path)
            except OperationFailure:
                pass
    
        def listPath(self, service_name, path):
            """
            列举目录下的文件和目录
            :param service_name: 服务名(samba服务器中/etc/samba/smb.conf的[]里的名称)
            :param path: 目录路径
            :return: path目录下的文件和目录
            """
            filenames = []
            for shareFile in self.samba.listPath(service_name, path):
                filename = shareFile.filename
                if filename == '.' or filename == '..':
                    continue        # 过滤下
                filenames.append(shareFile.filename)
            return filenames
    
    if __name__ == '__main__':
        local_dir = 'D:/test/'
        # local_dir = '/mnt/d/test/'
        smb_client = SMBClient('username', '123456', '127.0.0.1', 445)  # 也可以用139端口
        smb_client.connect()
        smb_client.download('test.txt', local_dir, 'share')  # 从共享文件夹中下载test.txt
        smb_client.createDir('share', 'test')  # 在共享文件夹中创建test目录
        smb_client.upload('test.txt', 'D:/test/', 'share', 'test')  # 将本地的test.txt上传至共享文件夹的test目录下
        print smb_client.listPath('share', 'test')  # 查看共享文件夹test目录下的文件和目录 
    
    另外,如果在SMBClient.connect的时候遇到了报错:UnicodeDecodeError: 'utf8' codec can't decode byte 0x81 in position 0: invalid start byte,那么在SMBConnection实例化时增加参数is_direct_tcp=True即可。
    smb_client = SMBClient('username', '123456', '127.0.0.1', 445, use_ntlm_v2=True, is_direct_tcp=True)
    

参考资料:
【1】玩转WSL-用Samba服务替代Win10原生的文件共享
【2】win10 启用wsl2 并设置wsl2子系统为Windows Terminal终端的默认启动项以及启动快捷键
【3】win10 WSL2问题解决WslRegisterDistribution failed with error: 0x800701bc
【4】Python——操作smb文件服务器(上传和下载)
【5】CentOS 7下Samba服务安装与配置详解

Logo

更多推荐