How do I mount a filesystem using Python?

Question:

I’m sure this is a easy question, my Google-fu is obviously failing me.

How do I mount a filesystem using Python, the equivalent of running the shell command mount ...?

Obviously I can use os.system to run the shell command, but surely there is a nice tidy, Python interface to the mount system call.

I can’t find it. I thought it would just be a nice, easy os.mount().

Asked By: jjh

||

Answers:

surely this is a nice tidy, python interface to the mount system call.

I can’t find it (I thought it would just be a nice, easy os.mount()).

Surely, there is none. What would this function do on Windows?

Use the shell command instead.

Answered By: Ferdinand Beyer

Mounting is a pretty rare operation, so it’s doubtful that there is any direct python way to do it.

Either use ctypes to do the operation directly from python, or else (and probably better), use subprocess to call the mount command (don’t use os.system() – much better to use subprocess).

Answered By: Douglas Leeder

Badly, mounting and unmounting belongs to the things that are highly system dependent and since they are

  • rarely used and
  • can affect system stability

There is no solution that is portable available. Since that, I agree with Ferdinand Beyer, that it is unlikely, a general Python solution is existing.

Answered By: Juergen

Import cdll from ctypes. Then load your os libc, then use libc.mount()

Read libc‘s docs for mount parameters

Answered By: marianov

Note that calling your libc mount function will require root privileges; Popen([‘mount’…) only will if the particular mounting isn’t blessed in fstab (it is the mount executable, setuid root, that performs these checks).

Answered By: David

As others have stated, a direct access to the syscall will not help you, unless you’re running as root (which is generally bad, for many reasons). Thus, it is best to call out to the “mount” program, and hope that /etc/fstab has enabled mounts for users.

The best way to invoke mount is with the following:

subprocess.check_call(["mount", what])

where what is either the device path, or the mountpoint path. If any problems arise, then an exception will be raised.

(check_call is an easier interface than Popen and its low-level brethren)

Answered By: gstein

Another option would be to use the fairly new sh module. According to its documentation it provides fluent integration with Shell commands from within Python.

I am trying it out now and it looks very promising.

from sh import mount

mount("/dev/", "/mnt/test", "-t ext4")

Also take a look at baking, which allows you to quickly abstract away commands in new functions.

Answered By: samvv

As others have pointed out, there is no built-in mount function. However, it is easy to create one using ctypes, and this is a bit lighter weight and more reliable than using a shell command.

Here’s an example:

import ctypes
import ctypes.util
import os

libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
libc.mount.argtypes = (ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_ulong, ctypes.c_char_p)

def mount(source, target, fs, options=''):
  ret = libc.mount(source.encode(), target.encode(), fs.encode(), 0, options.encode())
  if ret < 0:
    errno = ctypes.get_errno()
    raise OSError(errno, f"Error mounting {source} ({fs}) on {target} with options '{options}': {os.strerror(errno)}")

mount('/dev/sdb1', '/mnt', 'ext4', 'rw')
Answered By: Paul Donohue

I know this is old but I had a similar issue and pexpect solved it. I could mount my Windows shared drive using the mount command but I couldn’t pass my password in because it had to be escaped. I grew tired of escaping it and tried to use a credentials file which also caused issues. This seems to work for me.

password = "$wirleysaysneverquit!!!"

cmd = "sudo mount -t cifs -o username=myusername,domain=CORPORATE,rw,hard,nosetuids,noperm,sec=ntlm //mylong.evenlonger.shareddrivecompany.com/some/folder /mnt/folder -v"
p = pexpect.spawn( cmd )
p.expect( ": " )
print( p.before + p.after + password )
p.sendline( password )
p.expect( "rn" )

output = p.read()
arroutput = output.split("rn")
for o in arroutput:
    print( o )

Source: https://gist.github.com/nitrocode/192d5667ce9da67c8eac

Answered By: SomeGuyOnAComputer

You can use Python bindings for libmount from util-linux project:

import pylibmount as mnt

cxt = mnt.Context()
cxt.source = '/dev/sda1'
cxt.target = '/mnt/'
cxt.mount()

For more information see this example.

Answered By: yegorich
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.