Как я могу проверить, смонтирован ли том там, где предполагается использовать 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)
Insyte
источник
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

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

Magentron
источник
1

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

McJeff
источник