You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python代码访问远程路径?VM内SMB共享访问故障求助

解决虚拟机内SMB共享访问失败及结合os.walk遍历远程路径的问题

我来帮你梳理下问题的解决思路,结合你遇到的登录错误和遍历需求,给你几个可行的方案:

先排查NT_STATUS_LOGON_FAILURE错误的常见原因

这个报错大多和身份验证或网络配置有关,先把基础问题解决:

  • 凭据格式问题:如果是Windows主机的共享,用户名可能需要带上工作组/域名前缀,比如WORKGROUP\你的用户名,而不是单纯的用户名
  • SMB协议版本不兼容:虚拟机系统可能默认启用了旧版SMB1,而主机用的是SMB3,需要在虚拟机里开启SMB2/3支持(比如Linux下可以在挂载时加vers=3.0参数)
  • 网络模式问题:如果虚拟机用的是NAT模式,可能无法直接访问主机的SMB共享,建议切换到桥接模式或仅主机模式

方案一:挂载SMB共享到虚拟机本地,直接用os.walk

这是最直观的方式,把远程共享挂载成虚拟机的本地目录,之后os.walk就和操作本地文件夹完全一样了:

步骤(以Linux虚拟机为例):

  1. 安装SMB挂载工具:

    sudo apt install cifs-utils
    
  2. 创建挂载点目录:

    sudo mkdir /mnt/smb_shared
    
  3. 挂载共享(替换成你的实际信息):

    sudo mount -t cifs //主机IP/共享路径 /mnt/smb_shared -o username=你的用户名,password=你的密码,domain=工作组名,vers=3.0
    

    (vers=3.0指定用SMB3协议,避免版本兼容问题)

  4. Python中使用os.walk:

    import os
    # 直接遍历挂载后的目录
    for root, dirs, files in os.walk('/mnt/smb_shared'):
        print(f"当前目录:{root}")
        for file in files:
            print(f"文件:{os.path.join(root, file)}")
    

方案二:用pysmb库直接访问SMB共享(无需挂载)

如果不想挂载目录,可以用专门的SMB操作库pysmb,它支持直接遍历远程共享,模拟os.walk的功能:

  1. 安装pysmb:

    pip install pysmb
    
  2. 实现遍历的代码:

    from smb.SMBConnection import SMBConnection
    
    # 配置你的共享信息
    username = "你的用户名"
    password = "你的密码"
    server_ip = "主机IP"
    server_netbios_name = "主机的NetBIOS名称(比如主机名)"
    share_name = "共享的名称(比如主机上共享的文件夹名)"
    sub_path = "共享下的子路径(如果有的话)"
    
    # 创建连接
    conn = SMBConnection(username, password, "虚拟机客户端名称", server_netbios_name, use_ntlm_v2=True)
    conn.connect(server_ip, 445)  # SMB默认端口445或139
    
    # 模拟os.walk的递归遍历函数
    def smb_walk(conn, share, path):
        files = []
        dirs = []
        # 获取当前路径下的所有条目
        for item in conn.listPath(share, path):
            if item.filename in ['.', '..']:
                continue
            if item.isDirectory:
                dirs.append(item.filename)
            else:
                files.append(item.filename)
        yield path, dirs, files
        # 递归遍历子目录
        for dir_name in dirs:
            new_path = f"{path}/{dir_name}" if path else dir_name
            yield from smb_walk(conn, share, new_path)
    
    # 开始遍历
    for root, dirs, files in smb_walk(conn, share_name, sub_path):
        print(f"Root: {root}")
        print(f"子目录: {dirs}")
        print(f"文件: {files}\n")
    
    # 关闭连接
    conn.close()
    

方案三:修复wnc模块的路径错误

你之前的wnc代码路径格式不正确,UNC路径不需要把用户名写在路径里,正确的用法是:

from wnc import UncDirectory, UncCredentials

# 先创建凭据对象
creds = UncCredentials('你的用户名', '你的密码')
# UNC路径格式必须是 //IP地址/共享路径
unc_dir = UncDirectory(r'//主机IP/共享路径/', creds)

# 模拟os.walk的遍历
def wnc_walk(unc_dir):
    dirs = []
    files = []
    for entry in unc_dir.scandir():
        if entry.is_dir():
            dirs.append(entry.name)
        else:
            files.append(entry.name)
    yield unc_dir.path, dirs, files
    # 递归处理子目录
    for dir_name in dirs:
        sub_dir = unc_dir / dir_name
        yield from wnc_walk(sub_dir)

# 执行遍历
for root, dirs, files in wnc_walk(unc_dir):
    print(f"当前路径: {root} | 子目录: {dirs} | 文件: {files}")

内容的提问来源于stack exchange,提问作者Aashima Arora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:01:54