Come posso verificare se si /my/dirtrova sulla stessa partizione di /?
Questo è per l'integrazione all'interno di uno script. I supporti di collegamento devono essere gestiti correttamente. Le soluzioni compatibili POSIX sono benvenute.
Come posso verificare se si /my/dirtrova sulla stessa partizione di /?
Questo è per l'integrazione all'interno di uno script. I supporti di collegamento devono essere gestiti correttamente. Le soluzioni compatibili POSIX sono benvenute.
Risposte:
Puoi verificarlo con stat:
$ stat -c '%d %m' /proc/sys/
3 /proc
Ti mostra il numero del dispositivo e dove è stata montata la tua directory.
statcomando shell non è POSIX ...
Il comando seguente fornisce un nome univoco per il punto di montaggio contenente il file $file:
df -P -- "$file" | awk 'NR==2 {print $1}'
Funziona su qualsiasi sistema POSIX . L' -Popzione impone un formato prevedibile; il primo campo della seconda riga è il "nome del file system". Pertanto, per controllare due file si trovano nello stesso punto di montaggio:
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
Oppure, per salvare un paio di invocazioni di 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
Alcuni sistemi operativi possono avere spazi nei nomi dei volumi. In dfquesto caso non esiste un modo completamente affidabile per analizzare l' output.
Sotto il cofano, puoi identificare il filesystem contenente un file dal st_devcampo restituito da stat. Non esiste un modo portatile per farlo da uno script di shell. Alcuni sistemi hanno statun'utilità, ma la sua sintassi varia:
statsegnala il st_devcampo quando invocato come stat -c %D -- "$file".statcompatibile con i coreutils GNU. Altri hanno statsenza l' %copzione; puoi usarlo, stat -t -- "$file" | awk '{print $8}'ma funziona solo se il nome del file non contiene spazi bianchi o se fa stat -t -- "$file" | awk 'END {print $(NF-8)}'fronte a nomi di file arbitrari ma non con future aggiunte di campi statall'output.statun'utilità diversa che richiede stat -f %d -- "$file".statutilità.Se Perl è disponibile, è possibile utilizzare
perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"
e per fare il confronto:
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"
Si noti che ci sono alcuni casi angolari in cui il risultato desiderato non è chiaro. Ad esempio, con supporti bind di Linux, dopo mount --bind /foo /bar, /fooe /barsono considerati lo stesso file system. È sempre possibile che i due file si trovino effettivamente sullo stesso dispositivo, ma non lo saprai mai: ad esempio, se i file si trovano su due diversi montaggi di rete, il client non ha modo di sapere se il server sta esportando file system diversi.
Se i file sono directory e puoi scriverli, un altro metodo è quello di creare un file temporaneo e tentare di creare un collegamento reale. Questo riporta un risultato negativo su tutti i mount bind di 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"
dfnon sempre fornisce il nome del dispositivo, ma a volte un link simbolico ad esso non /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4rende dfaffidabile. L'unica opzione affidabile finora è l'utilizzo di una statsoluzione basata su.
dfriportato per il dispositivo, è coerente tra le due invocazioni, quindi va bene per un confronto.
dfreport /dev/sda6e /dev/disk/by-uuid/ca09b..., entrambi riferiti allo stesso dispositivo, ma punti di mount diversi. Il test di confronto delle stringhe ovviamente fallisce quando si prova con file da ciascun punto di montaggio.
mount /dev/sda6 /mnt1seguito da mount /dev/sda6 /mnt2opere come un fascino. cat /proc/mountsva bene con esso. Tuttavia, è solo da Wheezy che /dev/disk/by-uuid/ca09b...viene mostrato dfcome dispositivo per il filesystem di root. Ulteriori tentativi di montarlo usando questo simlink o la UUID=ca09b...sintassi del mount non finiscono per mostrare nient'altro che /dev/sda6in df(non so come riprodurre ciò che ha fatto durante il processo di avvio, ma non è questo il problema).
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Funziona con qualsiasi numero di percorsi.
$6), non il nome del dispositivo ( $1), quindi non dovrebbe essere un problema.
La migliore soluzione infallibile disponibile in POSIX è il confronto degli ID dispositivo dei file forniti dalla funzione stat (2) .
Perl ha una funzione statistica simile a quella indicata da Gilles :
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2
ma il "modo POSIX" è usare un programma C come:
./checksamedev file1 file2
quale codice sorgente è il seguente:
#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 gli ID dispositivo di entrambi i file sono uguali, sono ospitati sullo stesso filesystem, nel qual caso i comandi sopra restituiscono 0 (un altro valore altrimenti). Verificare con echo $?.
Funziona bene con i montaggi di bind, ma probabilmente non con i montaggi di rete.