Verifique se 2 diretórios estão hospedados na mesma partição no Linux

9

Como posso verificar se /my/dir está na mesma partição que / ?

Isso é para integração dentro de um script. Montagens de encadernação devem ser manuseadas corretamente. Soluções compatíveis com POSIX são bem vindas.

    
por Totor 21.03.2014 / 17:28

4 respostas

0

A melhor solução infalível disponível no POSIX é a comparação dos IDs do dispositivo dos arquivos fornecidos pelo stat (2) function .

O Perl tem uma função estatística similar como Gilles apontado :

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2

mas o "modo POSIX" é usar um programa C como:

./checksamedev file1 file2

qual código-fonte é o seguinte:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    struct stat s1, s2;
    if( argc==3 && lstat(argv[1], &s1)==0 && lstat(argv[2], &s2)==0 )
        return !(s1.st_dev == s2.st_dev);
    return 2;
}

Se os IDs de dispositivos de ambos os arquivos forem iguais, eles serão hospedados no mesmo sistema de arquivos; nesse caso, os comandos acima retornarão 0 (outro valor contrário). Verifique com echo $? .

Isso funciona bem com montagens de ligação, mas provavelmente não com montagens de rede.

    
por 01.05.2015 / 21:29
6

Você pode verificar isso com stat:

$ stat -c '%d %m' /proc/sys/
3 /proc

Mostra o número do dispositivo e onde seu diretório foi montado.

    
por 21.03.2014 / 17:36
5

O comando a seguir fornece um nome exclusivo para o ponto de montagem que contém o arquivo $file :

df -P -- "$file" | awk 'NR==2 {print $1}'

Funciona em qualquer sistema POSIX . A opção -P impõe um formato previsível; o primeiro campo da segunda linha é o “nome do sistema de arquivos”. Assim, para verificar dois arquivos estão sob o mesmo ponto de montagem:

if [ "$(df -P -- "$file1" | awk 'NR==2 {print $1}')" = \
     "$(df -P -- "$file2" | awk 'NR==2 {print $1}')" ]; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

Ou para salvar algumas chamadas de processo:

if df -P -- "$file1" "$file2" |
   awk 'NR!=1 {dev[NR] = $1} END {exit(dev[2] != dev[3])}'; then
  echo "$file1 and $file2 are on the same filesystem" ; fi

Alguns sistemas operacionais podem ter espaços em nomes de volume. Não há uma maneira completamente confiável de analisar a df output nesse caso.

Sob o capô, você pode identificar o sistema de arquivos que contém um arquivo pelo campo st_dev retornado por stat . Não há maneira portátil de fazer isso a partir de um script de shell. Alguns sistemas têm um utilitário stat , mas sua sintaxe varia:

  • Em sistemas Linux não incorporados, Cygwin ou outros sistemas com coreutils GNU, stat informa o campo st_dev quando chamado como stat -c %D -- "$file" .
  • Algumas instalações do BusyBox incluem um stat que é compatível com o GNU coreutils. Outros têm stat sem a opção %c ; você pode usar stat -t -- "$file" | awk '{print $8}' , mas isso só funcionará se o nome do arquivo não contiver espaço em branco ou stat -t -- "$file" | awk 'END {print $(NF-8)}' , que lida com nomes de arquivos arbitrários, mas não com futuros acréscimos de campos à stat output.
  • Os sistemas BSD têm um stat utility a> que requer stat -f %d -- "$file" .
  • Solaris, AIX e outros não possuem o utilitário stat .

Se o Perl estiver disponível, você pode usar

perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"

e para fazer a comparação:

perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"

Observe que há alguns casos em que o resultado desejado não está claro. Por exemplo, com as montagens de ligação do Linux, após mount --bind /foo /bar , /foo e /bar são considerados o mesmo sistema de arquivos. É sempre possível que os dois arquivos estejam realmente localizados no mesmo dispositivo, mas você nunca saberá: por exemplo, se os arquivos estiverem em duas montagens de rede diferentes, o cliente não terá como saber se o servidor está exportando sistemas de arquivos diferentes.

Se os arquivos são diretórios e você pode escrever para eles, outro método é criar um arquivo temporário e tentar criar um link físico. Este relata um resultado negativo nas montagens de ligação do Linux.

tmp1=$(TMPDIR=$dir1 mktemp)
tmp2=$(TMPDIR=$dir2 mktemp)
if ln -f -- "$tmp1" "$tmp2"; then
  echo "$dir1 and $dir2 are on the same filesystem, which supports hard links"
fi
rm -f "$tmp1" "$tmp2"
    
por 21.03.2014 / 20:16
4
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1

Funciona com qualquer número de caminhos.

    
por 21.03.2014 / 17:34