Jak mogę sprawdzić, czy wolumin jest zamontowany tam, gdzie powinien używać Pythona?

10

Mam skrypt zapasowy napisany w języku Python, który tworzy katalog docelowy przed skopiowaniem do niego katalogu źródłowego. Skonfigurowałem go tak, aby używał go /external-backupjako miejsca docelowego, do którego podłączam zewnętrzny dysk twardy. Po prostu uruchomiłem skrypt bez włączania (lub montowania) dysku twardego i stwierdziłem, że działa on normalnie, chociaż tworzy kopię zapasową na wewnętrznym dysku twardym, na którym nie ma wystarczającej ilości miejsca do wykonania kopii zapasowej.

Moje pytanie brzmi: jak mogę sprawdzić, czy wolumin jest zamontowany we właściwym miejscu przed zapisaniem na nim? Jeśli wykryję, że /external-backupnie jest zamontowany, mogę zapobiec zapisywaniu do niego.

Dodatkowe pytanie brzmi: dlaczego było to dozwolone, skoro system operacyjny wie, że katalog powinien znajdować się na innym urządzeniu, i co stałoby się z danymi (na wewnętrznym dysku twardym), czy powinienem później zamontować to urządzenie (zewnętrzny dysk twardy)? Oczywiście na tej samej ścieżce nie mogą znajdować się dwie kopie na różnych urządzeniach!

Z góry dziękuję!

Ben Hymers
źródło

Odpowiedzi:

23

Rzuciłbym okiem os.path.ismount().

Wstrzymano do odwołania.
źródło
1
Jedynym problemem jest to, że zwraca wartość logiczną i nie określa, czy jest tam właściwe urządzenie.
McJeff,
3
@McJeff: To prawda, że nie powiedzieć , który to mówi , jeśli . Jeśli nie ma żadnego urządzenia, zwróci false, a zapis w tej ścieżce zapisze w katalogu bazowym w nadrzędnym systemie plików. Więc jeśli zwróci false, wyślij błąd i nie pisz tam. Katalog /external-backupnie znajduje się na urządzeniu zewnętrznym, tylko w nadrzędnym systemie plików. System wie tylko, co to mountmówi, nie ma pojęcia, co powinno tam być. Nie ma nic specjalnego w „punkcie montowania” w systemie plików Unix. To tylko zwykły katalog.
Wstrzymano do odwołania.
To doskonale działa. Nie zamierzam chronić przed zamontowaniem innych woluminów, tylko że nie jest to nadrzędny system plików. Przepraszam innych odpowiadających, twoje odpowiedzi mogą dokładniej odpowiedzieć na moje pytanie, ale obawiam się, że nie bardzo wiedziałem, o co zapytać, jak można się domyślić;) I tak oceniłem was wszystkich .
Ben Hymers
Dobre wytłumaczenie!
McJeff,
5

Aby uzyskać ostateczną odpowiedź na coś, co wie tylko jądro, zapytaj jądro:

cat /proc/mounts

Ten plik można odczytać / przeanalizować tak, jakby był normalnym plikiem przy użyciu dowolnych narzędzi. W tym Python. Przykład szybkiego i brudnego:

#!/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
źródło
4

Najłatwiejszym sposobem sprawdzenia jest wywołanie mountza pomocą subprocessi sprawdzenie, czy tam się pojawi. Aby uzyskać dodatkowe środki, użyj os.readlink()zawartości, /dev/disk/by-*aby dowiedzieć się, które to urządzenie.

Ignacio Vazquez-Abrams
źródło
Moim zdaniem problem z tym podejściem polega na tym, że wynik mountjest w najlepszym wypadku niechlujny. Co robi mountwyjście jeśli mam zamontowany /dev/evil device on tourna /directory on which I mount devices? Analiza wyników może być niewiarygodna w takich przypadkach ...
przeglądając
2

Dodatkowa odpowiedź. Jeśli urządzenie zewnętrzne nie jest zamontowane, dane są zapisywane na partycji root na ścieżce /external-backup. Jeśli urządzenie zewnętrzne jest zamontowane, dane na partycji głównej nadal tam są, ale nie są osiągalne, ponieważ /external-backupteraz wskazują na urządzenie zewnętrzne.

Casual Coder
źródło
2

Stare pytanie, ale pomyślałem, że i tak przyczynię się do rozwiązania (na podstawie odpowiedzi Dennisa Williamsona i Ignacio Vazquez-Abramsa ). Ponieważ używam go w środowisku innym niż Linux do sprawdzania montowanych katalogów zdalnych, nie można używać / proc i mtab i nie przeprowadzono żadnych dodatkowych kontroli:

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

Udoskonalenia mile widziane!

Magentron
źródło
1

Plik / etc / mtab istnieje, aby poinformować Cię, co jest aktualnie zamontowane. Jest getmntentpołączenie, ale nie sądzę, aby zostało wyeksportowane do osmodułu. Szybki i brudny? Otwórz / etc / mtab i podziel. Upewnij się, że urządzenie jest obecne w kolumnie 0, a docelowy punkt podłączenia w kolumnie 1 jest poprawny.

McJeff
źródło