如何只在未挂载时挂载OS X卷?

2 投票
2 回答
1113 浏览
提问于 2025-04-17 20:39

我正在用一个Python脚本来挂载OS X的卷(也就是磁盘)。我想知道怎么才能避免在卷已经被挂载的情况下出现错误,这样脚本就不会因为无法挂载到本地目录而失败。

def volumeMounter(remote_dir, local_dir):
    # Create local dir if it does not exist
    if not os.path.exists( local_dir ):
        os.makedirs( local_dir )
    local_dir = os.path.abspath(local_dir)

    # Attempt mounting of server share
    retcode = subprocess.call(["/sbin/mount", "-t", "smbfs", remote_dir, local_dir])
    if retcode != 0:
        raise OSError("Mount operation failed")

2 个回答

1

你可以在 /Volumes 这个地方查看已挂载的路径,方法如下:

mountedpath = os.path.join("/Volumes", local_dir)
if not os.path.exists(mountedpath):
    retcode = subprocess.call(["/sbin/mount", "-t", "smbfs", remote_dir, local_dir])
    if retcode != 0:
        raise OSError("Mount operation failed")
else:
    print "Mounted path found"
1

这里有几个竞争条件。用Python和系统管理员的原则来说,就是“请求原谅比请求许可更简单”。在这个情况下,这意味着与其去猜测某个操作是否会成功,不如直接尝试这个操作,然后检查结果。

import errno
import os
import subprocess

def assert_remote_dir_is_mounted(remote_dir, local_dir):
    # Make sure the directory exists.
    try:
        # Try it first. This avoids race conditions where two processes check
        # for its existence at the same time.
        os.makedirs(local_dir)
    except OSError as exc:
        # The "already exists" error is OK. Only report other error conditions.
        if exc.errno != errno.EEXIST:
            raise

    retcode = subprocess.call(["/sbin/mount", "-t", "smbfs", remote_dir, local_dir])

    # The call succeeded
    if not retcode:
        return True

    # If it didn't succeed, see if the directory is on a different device
    # from its parent. If it is, then the directory was already mounted,
    # and hopefully on `remote_dir`. If that's sufficient, then you're done
    # here. If you really need to verify that it's mounted on `remote_dir`,
    # shell out to `mount` or otherwise check it.
    local_parent = os.path.abspath(os.path.join(local_dir, os.pardir))
    if os.stat(local_parent).st_dev != os.stat(local_dir).st_dev:
        return True

    return False
    # or raise SomeException("couldn't mount"), etc.

撰写回答