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"