如何用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虚拟机为例):
安装SMB挂载工具:
sudo apt install cifs-utils创建挂载点目录:
sudo mkdir /mnt/smb_shared挂载共享(替换成你的实际信息):
sudo mount -t cifs //主机IP/共享路径 /mnt/smb_shared -o username=你的用户名,password=你的密码,domain=工作组名,vers=3.0(
vers=3.0指定用SMB3协议,避免版本兼容问题)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的功能:
安装
pysmb:pip install pysmb实现遍历的代码:
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
相关产品推荐
相关产品推荐

