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"