Wie kann ich überprüfen, ob /my/dirsich auf derselben Partition befindet wie /?
Dies dient zur Integration in ein Skript. Bindungshalterungen sollten korrekt gehandhabt werden. POSIX-kompatible Lösungen sind willkommen.
Wie kann ich überprüfen, ob /my/dirsich auf derselben Partition befindet wie /?
Dies dient zur Integration in ein Skript. Bindungshalterungen sollten korrekt gehandhabt werden. POSIX-kompatible Lösungen sind willkommen.
Antworten:
Sie können dies mit stat überprüfen:
$ stat -c '%d %m' /proc/sys/
3 /proc
Zeigt Ihnen die Gerätenummer und den Ort an, an dem Ihr Verzeichnis bereitgestellt wurde.
statShell-Befehl ist nicht POSIX ...
Der folgende Befehl gibt einen eindeutigen Namen für den Einhängepunkt an, der die Datei enthält $file:
df -P -- "$file" | awk 'NR==2 {print $1}'
Dies funktioniert auf jedem POSIX- System. Die -POption legt ein vorhersehbares Format fest. Das erste Feld der zweiten Zeile ist der "Dateisystemname". Um zu überprüfen, ob sich zwei Dateien unter demselben Einhängepunkt befinden:
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
Oder, um einige Prozessaufrufe zu speichern:
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
Einige Betriebssysteme können Leerzeichen in Datenträgernamen enthalten. dfIn diesem Fall gibt es keine absolut zuverlässige Methode zum Parsen der Ausgabe.
Unter der Haube können Sie das Dateisystem, das eine Datei enthält, anhand des von zurückgegebenen st_devFelds identifizieren stat. Es gibt keine tragbare Möglichkeit, dies über ein Shell-Skript zu tun. Einige Systeme haben ein statDienstprogramm, aber die Syntax variiert:
statmeldet Cygwin oder andere Systeme mit GNU-Coreutils das st_devFeld beim Aufrufen als stat -c %D -- "$file".statdie mit GNU-Coreutils kompatibel ist. Andere haben statohne die %cOption; Sie können verwenden stat -t -- "$file" | awk '{print $8}', dies funktioniert jedoch nur, wenn der Dateiname kein Leerzeichen enthält oder stat -t -- "$file" | awk 'END {print $(NF-8)}'mit beliebigen Dateinamen, jedoch nicht mit zukünftigen Hinzufügungen von Feldern zur statAusgabe zurechtkommt.statNutzen, der dies erfordert stat -f %d -- "$file".statDienstprogramm.Wenn Perl verfügbar ist, können Sie verwenden
perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"
und um den Vergleich zu machen:
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"
Beachten Sie, dass es einige Eckfälle gibt, in denen das gewünschte Ergebnis nicht klar ist. Zum Beispiel mit Linux Bind Mounts, nach mount --bind /foo /bar, /foound /barwerden als das gleiche Dateisystem sein. Es ist immer möglich, dass sich die beiden Dateien tatsächlich auf demselben Gerät befinden, aber Sie werden es nie erfahren: Wenn sich die Dateien beispielsweise auf zwei verschiedenen Netzwerk-Mounts befinden, kann der Client nicht feststellen, ob der Server unterschiedliche Dateisysteme exportiert.
Wenn es sich bei den Dateien um Verzeichnisse handelt und Sie darauf schreiben können, besteht eine andere Methode darin, eine temporäre Datei zu erstellen und zu versuchen, eine feste Verknüpfung herzustellen. Dieser meldet ein negatives Ergebnis für alle Linux-Bindungs-Mounts.
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"
dfnicht gibt immer die Gerätenamen, aber irgendwann einen symbolischen Link , um es wie /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4macht dfnicht zuverlässig. Die einzige zuverlässige Option ist bisher die Verwendung einer statLösung auf Basis.
dfdes Geräts ist die Übereinstimmung zwischen den beiden Aufrufen konsistent, sodass ein Vergleich in Ordnung ist.
dfBericht /dev/sda6und /dev/disk/by-uuid/ca09b...beide beziehen sich auf dasselbe Gerät, aber unterschiedliche Mountpunkte. Der Zeichenfolgenvergleichstest schlägt offensichtlich fehl, wenn versucht wird, Dateien von jedem Einhängepunkt zu verwenden.
mount /dev/sda6 /mnt1gefolgt von mount /dev/sda6 /mnt2Arbeiten wie ein Zauber. cat /proc/mountsist gut damit. Jedoch ist es , da nur Wheezy , die /dev/disk/by-uuid/ca09b...in gezeigt wird , dfwie die Vorrichtung für das Root - Dateisystem. Weitere Versuche, es über diesen Simlink oder die UUID=ca09b...Mount-Syntax zu mounten, zeigen nichts anderes als /dev/sda6in df(Ich weiß nicht, wie ich reproduzieren soll, was es während des Startvorgangs getan hat, aber das ist hier nicht das Problem).
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Funktioniert mit einer beliebigen Anzahl von Pfaden.
dfist nicht immer eine gute Idee .
$6), nicht den Gerätenamen ( $1), also sollte das kein Problem sein.
Die beste narrensichere Lösung in POSIX ist der Vergleich der Geräte-IDs der Dateien, die von der Funktion stat (2) bereitgestellt werden .
Perl hat eine ähnliche Stat Funktion wie Gilles wies darauf hin :
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2
Der "POSIX-Weg" besteht jedoch darin, ein C-Programm wie das folgende zu verwenden:
./checksamedev file1 file2
Welcher Quellcode lautet wie folgt:
#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;
}
Wenn die Geräte-IDs beider Dateien gleich sind, werden sie auf demselben Dateisystem gehostet. In diesem Fall geben die obigen Befehle 0 zurück (ansonsten ein anderer Wert). Überprüfen Sie mit echo $?.
Dies funktioniert gut mit Bindungs-Mounts, aber wahrscheinlich nicht mit Netzwerk-Mounts.