Apagando com segurança um diretório somente se não for um ponto de montagem

1

Infelizmente, estou sendo forçado a trabalhar com um software que manipula e desmonta automaticamente um volume de rede muito mal. tem uma tendência irritante de deixar um diretório onde estava o ponto de montagem, mas não consegue lidar adequadamente com isso quando monta o volume novamente (é supostamente arrumado, mas muitas vezes não ).

Naturalmente eu estou nos desenvolvedores para corrigir isso, mas enquanto isso eu preciso fazer alguma coisa para arrumar o (s) ponto (s) de montagem.

Então, essencialmente, o que eu preciso fazer é remover o diretório, mas somente se não for atualmente um ponto de montagem (já que não quero excluir o conteúdo do volume por acidente).

Agora, posso obter o ID do dispositivo do diretório e compará-lo ao ID do dispositivo do root com bastante facilidade, mas existe a possibilidade de uma condição de corrida se eu usar essa comparação, ou seja, se o volume estiver montado entre verificando IDs de dispositivos e chamando rm -r /mnt/point .

Existem alternativas? Fiquei intrigado com a possibilidade de usar a opção find do comando -xdev , mas não tenho certeza de como eu realmente forneceria um ponto de comparação, pois find /mnt/point -xdev não funcionará como destino e seu conteúdo é o mesmo dispositivo.

Além disso, usar rmdir na suposição de que a pasta restante ficará sempre vazia parece não ser confiável, já que em alguns sistemas um ponto de montagem pode ter um arquivo dentro dele; O macOS, por exemplo, deixa um arquivo .autodiskmounted dentro dele. Enquanto eu poderia criar uma lista de tais casos e lidar com eles, seria bom (e esperançosamente útil para outros) ter uma solução de propósito mais geral para referência futura, se tal coisa for possível.

    
por Haravikk 26.09.2017 / 12:16

3 respostas

3

Se o diretório for um ponto de montagem, ele estará ocupado e você não poderá renomeá-lo.

$ sudo mv /mnt /mnt.old
mv: cannot move '/mnt' to '/mnt.old': Device or resource busy

Se for apenas um diretório comum, você poderá renomeá-lo.

$ sudo mv /mnt /mnt.old

Se a movimentação for bem-sucedida, recrie o diretório de montagem e exclua o diretório renomeado. Opcionalmente, você pode validar o diretório renomeado como parte do sistema de arquivos que você espera antes da remoção.

    
por 27.09.2017 / 02:00
1

Se você estiver usando o Linux

Você pode testar se um diretório é um ponto de montagem usando mountpoint .

Para evitar que o ponto de montagem apareça / desapareça entre o teste e o rm -r , você precisa executar o script em um mount namespace com subárvore privada (as montagens não se propagam de / para o novo namespace). Isso pode ser feito com unshare .

unshare -m --propagation private -- "<delete script>"

Tudo no mesmo script:

#!/bin/sh

unshare -m --propagation private -- sh -e <<EOF

if ! mountpoint -q "<path>"; then
    rm -r "<path>"
fi

EOF
    
por 26.09.2017 / 12:23
0

Você não pode rmdir um diretório que não esteja vazio ou um que seja um ponto de montagem. Então, isso irá satisfazer sua exigência:

rm -f mountpoint/.autodiskmounted    # MacOS cookie
rmdir mountpoint 2>/dev/null

Se você estiver executando um script com o sair no conjunto de erros , poderá usar rmdir ... || true . (Observe que --ignore-fail-on-non-empty é de pouca utilidade, porque obteremos um erro não detectado ao tentar remover um ponto de montagem.)

Devo salientar que não tenho acesso a um sistema Mac, por isso não posso testar se o arquivo .autodiskmounted está presente quando o sistema de arquivos está realmente montado ou se é um espaço reservado para quando o sistema de arquivos é desmontado. / p>     

por 26.09.2017 / 17:08