Como posso verificar se um volume está montado onde deveria estar usando Python?

9

Eu tenho um script de backup escrito em Python que cria o diretório de destino antes de copiar o diretório de origem para ele. Eu o configurei para usar /external-backupcomo destino, onde é montado um disco rígido externo. Acabei de executar o script sem que o disco rígido estivesse ligado (ou montado) e descobri que estava funcionando normalmente, embora fazendo um backup no disco rígido interno, que não tem espaço suficiente para fazer o backup.

Minha pergunta é: como posso verificar se o volume está montado no lugar certo antes de gravá-lo? Se eu conseguir detectar que /external-backupnão está montado, posso impedir a gravação.

A questão do bônus é por que isso foi permitido, quando o sistema operacional sabe que o diretório deve estar em outro dispositivo e o que aconteceria com os dados (no disco rígido interno) devo montar posteriormente esse dispositivo (o disco rígido externo)? Claramente, não pode haver duas cópias em dispositivos diferentes no mesmo caminho!

Desde já, obrigado!

Ben Hymers
fonte

Respostas:

22

Eu daria uma olhada os.path.ismount().

Pausado até novo aviso.
fonte
1
O único problema é que ele retorna um booleano e não especifica se o dispositivo certo está lá.
McJeff
3
@ McJeff: É verdade que não diz o que diz se . Se nenhum dispositivo estiver lá, ele retornará false e uma gravação nesse caminho será gravada no diretório subjacente no sistema de arquivos pai . Portanto, se retornar falso, cometa um erro e não escreva lá. O diretório /external-backupnão vive em um dispositivo externo, ele vive no sistema de arquivos pai. O sistema sabe apenas o que mountdiz, não faz ideia do que deve estar lá. Não há nada de especial em um "ponto de montagem" em um sistema de arquivos Unix. É apenas um diretório regular.
Pausado até novo aviso.
Isso faz o trabalho perfeitamente. Não vou me proteger contra outros volumes montados lá, apenas que não é o sistema de arquivos pai. Desculpe os outros respondentes, suas respostas podem responder mais exatamente à minha pergunta, mas receio não saber o que pedir em primeiro lugar, como você pode dizer;) classifiquei todos vocês de qualquer maneira .
Ben Hymers
Boa explicação!
McJeff
5

Para uma resposta definitiva para algo que apenas o kernel sabe com certeza, pergunte ao kernel:

cat /proc/mounts

Esse arquivo pode ser lido / analisado como se fosse um arquivo normal, usando as ferramentas que você desejar. Incluindo Python. Exemplo rápido e sujo:

#!/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
fonte
4

A maneira mais fácil de verificar é invocar mountvia subprocesse ver se aparece lá. Para obter crédito extra, use os.readlink()o conteúdo de /dev/disk/by-*para descobrir qual dispositivo é.

Ignacio Vazquez-Abrams
fonte
A meu ver, o problema dessa abordagem é que a saída de mounté definida na melhor das hipóteses. O que faz mountde saída se eu tiver montado /dev/evil device on tourem /directory on which I mount devices? A análise da saída pode não ser confiável nesses casos ...
skyking 26/10/18
2

Resposta bônus. Se o dispositivo externo não estiver montado, os dados serão gravados na partição raiz no caminho /external-backup. Se o dispositivo externo estiver montado, os dados na partição raiz ainda estarão lá, mas não /external-backuppoderão ser acessados ​​porque agora estão apontando para o dispositivo externo.

Casual Coder
fonte
2

Pergunta antiga, mas pensei em contribuir de qualquer maneira com minha solução (com base na resposta de Dennis Williamson e Ignacio Vazquez-Abrams ). Como estou usando-o em um ambiente não Linux para verificar a montagem de diretórios remotos, / proc e mtab não podem ser usados ​​e nenhuma verificação adicional foi implementada:

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

Melhorias bem-vindas!

Magentron
fonte
1

O arquivo / etc / mtab existe para informar o que está montado atualmente. Há uma getmntentchamada, mas acho que não foi exportada no osmódulo. O rápido e sujo? Abra / etc / mtab e divida. Verifique se o dispositivo está presente na coluna 0 e se o ponto de montagem de destino na coluna 1 está correto.

McJeff
fonte