Como posso verificar se /my/direstá na mesma partição que /?
Isto é para integração dentro de um script. As montagens de ligação devem ser manuseadas corretamente. As soluções compatíveis com POSIX são bem-vindas.
Como posso verificar se /my/direstá na mesma partição que /?
Isto é para integração dentro de um script. As montagens de ligação devem ser manuseadas corretamente. As soluções compatíveis com POSIX são bem-vindas.
Respostas:
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.
statcomando shell não é POSIX ...
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}'
Isso funciona em qualquer sistema POSIX . A -Popção impõe um formato previsível; o primeiro campo da segunda linha é o "nome do sistema de arquivos". Portanto, para verificar dois arquivos estão no 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 invocações 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 nos nomes dos volumes. Não há uma maneira completamente confiável de analisar a dfsaída neste caso.
Sob o capô, você pode identificar o sistema de arquivos que contém um arquivo pelo st_devcampo retornado por stat. Não há maneira portátil de fazer isso a partir de um script de shell. Alguns sistemas têm um statutilitário, mas sua sintaxe varia:
statrelata o st_devcampo quando chamado como stat -c %D -- "$file".statcompatível com os coreutils GNU. Outros têm statsem a %copção; 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)}'lidar com nomes arbitrários de arquivos, mas não com futuras adições de campos à statsaída.statutilitário diferente que requer stat -f %d -- "$file".statutilidade.Se o Perl estiver disponível, você poderá 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 existem alguns casos de canto em que o resultado desejado não é claro. Por exemplo, com montagens bind do Linux, depois de mount --bind /foo /bar, /fooe /barsã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 gravá-los, 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"
dfnem sempre fornece o nome do dispositivo, mas às vezes um link simbólico para ele, como /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4tornar dfnão confiável. Até agora, a única opção confiável é usar uma statsolução baseada em.
dfrelatado para o dispositivo, ele é consistente entre as duas invocações; portanto, é bom fazer uma comparação.
dfrelatório /dev/sda6e /dev/disk/by-uuid/ca09b..., ambos referentes ao mesmo dispositivo, mas com pontos de montagem diferentes. O teste de comparação de cadeias obviamente falha ao tentar com arquivos de cada ponto de montagem.
mount /dev/sda6 /mnt1seguido de mount /dev/sda6 /mnt2trabalhos como um encanto. cat /proc/mountsestá bem com isso. No entanto, somente a partir do Wheezy /dev/disk/by-uuid/ca09b...é mostrada dfcomo o dispositivo para o sistema de arquivos raiz. Tentativas adicionais de montá-lo usando este simlink ou a UUID=ca09b...sintaxe mount não terminam mostrando nada além de /dev/sda6in df(não sei como reproduzir o que ele fez durante o processo de inicialização, mas essa não é a preocupação aqui).
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Funciona com qualquer número de caminhos.
dfé não sempre uma boa idéia .
$6), não o nome do dispositivo ( $1), para que não seja um problema.
A melhor solução infalível disponível no POSIX é a comparação dos IDs de dispositivos dos arquivos fornecidos pela função stat (2) .
Perl tem uma função stat semelhante à que Gilles apontou :
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2
mas a "maneira 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 dispositivo dos dois arquivos forem iguais, eles serão hospedados no mesmo sistema de arquivos; nesse caso, os comandos acima retornarão 0 (outro valor, caso contrário). Verifique com echo $?.
Isso funciona bem com montagens de ligação, mas provavelmente não funcionará com montagens de rede.