Using pysmbc to read files over samba

后端 未结 5 2143
忘了有多久
忘了有多久 2020-12-30 13:12

I am using the python-smbc library on Ubuntu to access a samba share. I can access the directory structure fine, I am however not sure how to access actual files and their c

相关标签:
5条回答
  • 2020-12-30 13:59

    If you've managed to get the directory structure then you have a working context. The key to actually accessing files is the undocumented flags argument of Context.open. (I haven't figured out what mode is for either but it doesn't seem necessary.)

    flags is how you tell pysmbc what type of access to the file you want. You do that by passing it an integer made by bitwise ORing (|) flags from the os module together. Specifically the flags you want or suffixed with os.O_ (see a list in the Python documentation here).

    For example, to write to a file you would set flags to os.O_WRONLY (equiavlent to using "w" as the mode parameter of the built in open function) and to append to a file that might already exist use os.O_WRONLY | os.O_APPEND | os.O_CREAT (equivalent to "a+").

    That call will then return a file object which you can use like any normal, local file.

    0 讨论(0)
  • 2020-12-30 14:01

    I would stick with smbfs. It's only a matter of time before you want to access those shared files with something other than Python.

    0 讨论(0)
  • 2020-12-30 14:06

    I also have had trouble using smbfs (random system lockdowns and reboots) and needed a quick answer.

    I've also tried the smbc module but couldn't get any data with it. I went just as far as accessing the directory structure, just like you.

    Time was up and I had to deliver the code, so I took a shortcut:

    I wrote a small wrapper around a "smbclient" call. It is a hack, ugly, really ugly, but it works for my needs. It is being used in production on the company I work.

    Here's some example usage:

    >>> 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')
    

    The programmer before me was using a "bash" file with lots of smbclient calls, so I think my solution is at least better.

    I have uploaded it here, so you can use it if you want. Bitbucket repository is here. If you find a better solution please tell me and I'll replace my code too.

    0 讨论(0)
  • 2020-12-30 14:13

    Provided you have an open context (see the unit tests here)
    * 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()
    

    To open a context just define an authentication function

    ctx = smbc.Context()
    
    def auth_fn(server, share, workgroup, username, password):
        return (workgroup, settings.USERNAME, settings.PASSWORD)
    
    ctx.optionNoAutoAnonymousLogin = True
    ctx.functionAuthData = auth_fn
    
    0 讨论(0)
  • 2020-12-30 14:13

    If don't know if this is more clearly stated, but here's what I gleaned from this page and sorted out from a little extra Google-ing:

    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()
    
    0 讨论(0)
提交回复
热议问题