使用pysmbc通过Samba读取文件

7 投票
5 回答
32177 浏览
提问于 2025-04-15 12:12

我在Ubuntu上使用python-smbc库来访问samba共享。目录结构我能顺利访问,但我不太确定怎么访问实际的文件和它们的内容。这个网页(https://fedorahosted.org/pysmbc/)没有提到相关内容,代码是用C/C++写的,文档也很少,所以我不太清楚该怎么用。

我知道Context.open(用于文件)需要uri、flags和mode,但我不知道flags和mode具体是什么。

有没有人使用过这个库,或者有示例可以展示如何用它读取文件?

理想情况下,我当然希望使用smbfs挂载,但当我用smbmount挂载同一个共享时,所有文件夹都是空的。不过我可以用smbclient用同样的凭证正常浏览。

5 个回答

2

我不确定这是否说得更清楚,但这是我从这个页面上理解到的内容,并通过一些额外的谷歌搜索整理出来的:

def do_auth (server, share, workgroup, username, password):
  return ('MYDOMAIN', 'myacct', 'mypassword')


# Create the context
ctx = smbc.Context (auth_fn=do_auth)
destfile = "myfile.txt"
source = open('/home/myuser/textfile.txt', 'r')
# open a SMB/CIFS file and write to it
file = ctx.open ('smb://server/share/folder/'+destfile, os.O_CREAT | os.O_WRONLY)
for line in source:
        file.write (line)
file.close()
source.close()

# open a SMB/CIFS file and read it to a local file
source = ctx.open ('smb://server/share/folder/'+destfile, os.O_RDONLY)
destfile = "/home/myuser/textfile.txt"
fle = open(destfile, 'w')
for line in source:
        file.write (line)
file.close()
source.close()
3

只要你有一个打开的上下文(可以参考这里的单元测试)
* https://github.com/ioggstream/pysmbc/tree/master/tests

suri =  'smb://' + settings.SERVER + '/' + settings.SHARE + '/test.dat'  
dpath = '/tmp/destination.out'

# open smbc uri
sfile = ctx.open(suri, os.O_RDONLY)

# open local target where to copy file
dfile = open(dpath, 'wb')

#copy file and flush
dfile.write(sfile.read())
dfile.flush()

#close both files
sfile.close()    
dfile.close()

要打开一个上下文,只需要定义一个认证函数

ctx = smbc.Context()

def auth_fn(server, share, workgroup, username, password):
    return (workgroup, settings.USERNAME, settings.PASSWORD)

ctx.optionNoAutoAnonymousLogin = True
ctx.functionAuthData = auth_fn
12

我也遇到过使用smbfs的问题,比如系统随机崩溃和重启,所以我需要一个快速的解决办法。

我也试过smbc这个模块,但没能用它获取到任何数据。我只能访问目录结构,就像你一样。

时间不够了,我得交代码,所以我走了个捷径:

我写了一个小工具,围绕着一个smbclient的调用。这是个临时解决方案,虽然很丑,真的很丑,但满足我的需求。现在在我工作的公司里已经在生产环境中使用了。

下面是一些使用示例:

>>> smb = smbclient.SambaClient(server="MYSERVER", share="MYSHARE", 
                                username='foo', password='bar', domain='baz')
>>> print smb.listdir(u"/")
[u'file1.txt', u'file2.txt']
>>> f = smb.open('/file1.txt')
>>> data = f.read()
>>> f.close()
>>> smb.rename(u'/file1.txt', u'/file1.old')

在我之前的程序员使用了一个包含很多smbclient调用的“bash”文件,所以我觉得我的解决方案至少要好一些。

我把它上传到这里,你可以想用的话就用它。Bitbucket的代码库在这里。如果你找到更好的解决方案,请告诉我,我也会更新我的代码。

撰写回答