Как я могу проверить, смонтирован ли том там, где предполагается использовать Python?


9

У меня есть скрипт резервного копирования, написанный на Python, который создает каталог назначения перед копированием в него исходного каталога. Я настроил его для использования в /external-backupкачестве места назначения, где я подключаю внешний жесткий диск. Я просто запустил сценарий без включения (или подключения) жесткого диска и обнаружил, что он работает в обычном режиме, хотя и создает резервную копию на внутреннем жестком диске, где недостаточно места для резервного копирования.

Мой вопрос: как я могу проверить, смонтирован ли том в нужном месте, прежде чем писать в него? Если я могу обнаружить, что /external-backupэто не смонтировано, я могу предотвратить запись в него.

Дополнительный вопрос заключается в том, почему это было разрешено, когда ОС знает, что каталог должен находиться на другом устройстве, и что произойдет с данными (на внутреннем жестком диске), если я позже подключу это устройство (внешний жесткий диск)? Очевидно, что не может быть двух копий на разных устройствах по одному пути!

Заранее спасибо!

Ответы:


22

Я бы посмотрел на os.path.ismount().


1
Единственная проблема заключается в том, что он возвращает логическое значение и не указывает, есть ли нужное устройство.
МакДжефф

3
@McJeff: это правда, он не говорит, что он говорит, если . Если там нет ни одного устройства, оно вернет false и запись в этот путь приведет к записи в базовый каталог в родительской файловой системе. Так что, если он возвращает false, выдайте ошибку и не пишите там. Каталог /external-backupне находится на внешнем устройстве, он находится в родительской файловой системе. Система знает только то, что mountговорит это, она не имеет ни малейшего представления, что должно быть там. Нет ничего особенного в «точке монтирования» в файловой системе Unix. Это просто обычный каталог.
Приостановлено до дальнейшего уведомления.

Это делает работу отлично. Я не собираюсь защищать от монтирования там других томов, просто это не родительская файловая система. Извините других ответчиков, ваши ответы могут ответить на мой вопрос более точно, но я боюсь, что я не совсем знал, что спросить, во-первых, как вы могли бы сказать;) Я все равно оценил вас всех ,
Бен Хаймерс

Хорошее объяснение!
МакДжефф

5

Для окончательного ответа на что-то, что точно знает только ядро, спросите ядро:

cat /proc/mounts

Этот файл можно читать / анализировать, как если бы это был обычный файл, используя любые инструменты, которые вам нравятся. Включая Python. Quick-N-грязный пример:

#!/usr/bin/python

d = {}

for l in file('/proc/mounts'):
    if l[0] == '/':
        l = l.split()
        d[l[0]] = l[1]

import pprint

pprint.pprint(d)

4

Самый простой способ проверить это - вызвать mountvia subprocessи посмотреть, появится ли он там. Для дополнительной информации используйте os.readlink()содержимое, /dev/disk/by-*чтобы выяснить, какое это устройство.


На мой взгляд, проблема с этим подходом заключается в том, что результат работы mountопределяется в лучшем случае небрежно. Что mountвыводит, если я смонтирован /dev/evil device on tourна /directory on which I mount devices? Парсинг вывода может быть ненадежным в таких случаях ...
скайкинг

2

Бонусный ответ. Если внешнее устройство не подключено, данные записываются в корневой раздел по пути /external-backup. Если подключено внешнее устройство, данные в корневом разделе все еще там, но они недоступны, потому что /external-backupтеперь они указывают на внешнее устройство.


2

Старый вопрос, но я думал, что в любом случае внесу свое решение (основываясь на ответах Денниса Уильямсона и Игнасио Васкеса-Абрамса ). Поскольку я использую его в среде, отличной от Linux, для проверки монтирования удаленных каталогов, / proc и mtab не могут быть использованы, и никакие дополнительные проверки не были реализованы:

def is_mounted(special, directory):
    search_prefix = '{} on {}'.format(special, directory.rstrip('/'))

    if os.path.ismount(directory):
        mounts = subprocess.check_output(['mount']).split('\n')

        for line in mounts:
            if line[:len(search_prefix)] == search_prefix:
                return True;

    return False

Улучшения приветствуются!


1

Файл / etc / mtab существует, чтобы сообщить вам, что в данный момент смонтировано. Есть getmntentвызов, но я не думаю, что он экспортируется в osмодуль. Быстрая и грязная? Откройте / etc / mtab и разбейте. Убедитесь, что ваше устройство присутствует в столбце 0, а точка монтирования в столбце 1 указана правильно.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.