4
\$\begingroup\$

I have a use case where I need to check, whether / is mounted read-only. Here's the module where I implemented this check:

"""Check mount points."""

from __future__ import annotations
from contextlib import suppress
from os import linesep
from pathlib import Path
from re import fullmatch
from subprocess import check_output
from typing import Any, Iterator, NamedTuple


__all__ = ['mount', 'root_mounted_ro']


MOUNT_REGEX = r'(.+) on (.+) type (.+) \((.+)\)'


class MountPoint(NamedTuple):
    """Representation of mount points."""

    what: str
    where: Path
    type: str
    flags: list[str]

    @classmethod
    def from_string(cls, string: str) -> MountPoint:
        """Creates a mount point from a string."""
        if (match := fullmatch(MOUNT_REGEX, string)) is None:
            raise ValueError('Invalid mount value:', string)

        what, where, typ, flags = match.groups()
        return cls(what, Path(where), typ, flags.split(','))

    def to_json(self) -> dict[str, Any]:
        """Return a JSON-ish dict."""
        return {
            'what': self.what,
            'where': str(self.where),
            'type': self.type,
            'flags': self.flags
        }


def mount() -> Iterator[MountPoint]:
    """Yields mount points on the system."""

    for line in check_output('mount', text=True).split(linesep):
        with suppress(ValueError):
            yield MountPoint.from_string(line)


def root_mounted_ro() -> bool | None:
    """Check whether / is mounted read-only."""

    for mnt in mount():
        if mnt.where == Path('/'):
            return 'ro' in mnt.flags

    return None

Is there a better approach than parsing the output of mount using a regex?

\$\endgroup\$
2
  • \$\begingroup\$ What flavours of Linux do you anticipate needing to support? \$\endgroup\$ Commented Jul 15, 2022 at 21:42
  • \$\begingroup\$ This was originally written for Arch Linux. \$\endgroup\$ Commented Jul 16, 2022 at 7:48

1 Answer 1

2
\$\begingroup\$

Is there a better approach than parsing the output of mount using a regex?

Probably?

You care about machine legibility, not human legibility; so if you were sticking to a basic mountpoint search you should prefer reading /proc/mounts instead of calling mount.

However, you also only care about one specific path, so you might be better off calling findmnt --target /. This will require less parsing.

\$\endgroup\$

You must log in to answer this question.