Wie kann man in * nix feststellen, auf welchem ​​Dateisystem sich eine bestimmte Datei befindet?

12

Gibt es in einer allgemeinen, modernen Unix-Umgebung (z. B. GNU / Linux, GNU / Solaris oder Mac OS X) eine gute Möglichkeit, um festzustellen, auf welchem ​​Mountpunkt und Dateisystemtyp sich ein bestimmter absoluter Dateipfad befindet?

Ich nehme an, ich könnte den mountBefehl ausführen und die Ausgabe manuell analysieren und mit meinem Dateipfad vergleichen, aber bevor ich das tue, frage ich mich, ob es einen eleganteren Weg gibt.

Ich entwickle ein BASH-Skript, das erweiterte Attribute verwendet, und möchte, dass es für eine Vielzahl von Dateisystemen und Hostumgebungen das Richtige tut (soweit dies möglich ist).

Smokris
quelle

Antworten:

19

Der Befehl df(1)akzeptiert ein oder mehrere Argumente und gibt den Mountpunkt und das Gerät, auf dem sich diese Datei oder dieses Verzeichnis befindet, sowie Verwendungsinformationen zurück. Sie können dann den Pfad oder das Gerät verwenden, um den Dateisystemtyp in der Ausgabe von mount -voder ähnlichem nachzuschlagen .

Leider sind die Ausgabeformate von beiden dfund mountsystemabhängig; Es gibt keinen offensichtlichen Standard, zumindest wie ich zwischen Solaris, NetBSD und Mac OS X sehen kann.

Morven
quelle
1
df -Psollte auf jedem POSIX-kompatiblen System eine standardisierte Ausgabe erzeugen. Bei einigen gooferen Systemen muss möglicherweise auch eine magische Umgebungsvariable wie POSIXLY_CORRECT festgelegt werden.
Dan Moulding
Beispiel df /path-to-the-directorygibt Ihnen die enthaltende Partition dieses Verzeichnisses
Hasanuzzaman Sattar
7

Sie könnten stat verwenden . Der Befehl stat --printf '% d' filename.txt gibt die Gerätenummer als Hex / Dezimal zurück.

Zoredache
quelle
Also, wie kann man den Gerätenamen auf dieser Basis finden?
Daisy
Sie müssen alle Gerätedateien in / dev / durchsuchen und eine mit der gleichen untergeordneten Nummer wie stat nachschlagen.
Wiesław Herr
stat --printf "%d"gibt zwar die untergeordnete Nummer eines Geräts an, es muss jedoch noch mehr Arbeit geleistet werden, um den Gerätenamen und das angehängte Dateisystem abzurufen.
Craig McQueen
2
Möglicherweise handelt es sich um eine Neuerung, stat --format '%m' $filedie Ihnen jedoch den Mount-Punkt und stat --file-system --format '%T' $mountden Namen des Dateisystemtyps liefert.
Roaima
1
@TomHale: Ich erinnere mich nicht, um ehrlich zu sein. Aber ich erinnere mich, dass es nicht funktioniert hat. Zugegeben, ich hätte die Distribution, die Kernel-Version usw. angeben sollen. Aber wenn Sie angeben, dass sie funktioniert, kann dies auch bedeuten, dass sie inzwischen behoben wurde. Wenn das
Nettoergebnis
3

Nur für eine bestimmte Datei ist es so einfach wie

df -T "${FILE}" | awk '{print $2}' | tail -n1
Julian Pawlowski
quelle
Funktioniert nicht mit btrfs!
0xC0000022L
2

Hm. Für den Mount-Punkt können Sie die Hierarchie nach oben gehen, bis sich st_dev ändert (dann haben Sie gerade eine Mount-Grenze überschritten). Es gibt GNU statfür Bash-Skripte; Ich weiß jedoch nicht, wie man den Dateisystemtyp erraten kann, ohne ihn zu analysieren /proc/mountsoder durch Ausprobieren (dh Fehler behandeln, nachdem erweiterte Attribute festgelegt wurden).

ΤΖΩΤΖΙΟΥ
quelle
2

Ein Gotcha bei der Verwendung dfist , dass , wenn der Gerätename in der Ausgabe lange ist es die Zeile umgebrochen wird , so dass Sie nicht nur die letzte Zeile greifen. Entfernen Sie stattdessen die erste Zeile, greifen Sie die neue erste Zeile und drucken Sie das erste Feld aus:

#!/usr/bin/env bash

path=$1
curdir=$(pwd)
cd $path
df . | tail -n +2 | head -1 | awk '{print $1}'
cd $curdir
mage2k
quelle
3
Vermeiden Sie dieses Problem, indem Sie 'df -P' verwenden, um die Ausgabe im POSIX-Format und ohne Zeilenumbruch zu erhalten.
MikeyB
2

Es scheint einen Haken bei df und btrfs unter Linux zu geben. Wenn Sie df auffordern, den Einhängepunkt für ein eingehängtes btrfs-Volume zu suchen, wird das Richtige getan. In diesem Fall ist Joe ein Unterverzeichnis von / m / whale / backup.

# df /srv/backup/joe
Filesystem      1K-blocks      Used  Available Use% Mounted on
/dev/md126     2930135488 307676684 2619663252  11% /m/whale/backup

Wenn das Verzeichnis, auf das verwiesen wird, ein Sub-Volume ist, wird der Mount-Punkt nicht mehr angezeigt.

# df /srv/backup/joe/code
Filesystem      1K-blocks      Used  Available Use% Mounted on
-              2930135488 307676684 2619663252  11% /a/whale/backup/joe/code

Das / a / whale / backup ist laut Kernel der einzige Einhängepunkt.

# mount | grep whale
/dev/md126 on /a/whale/backup type btrfs (rw,relatime,space_cache)

FWIW, stat macht dasselbe:

# stat --printf '%m\n' /srv/backup/joe/code
/a/whale/backup/joe/code
Marc Singer
quelle
1

Unter /programming/2167558/give-the-mount-point-of-a-path :

 df -P $path  | tail -1 | awk '{ print $NF}'

Funktioniert überall, wo ich getestet habe, sowohl für * BSDs als auch für sysVs und für verrückte automounted-Verzeichnisse. Es würde mich sehr freuen, von einem Fall zu hören, in dem dies fehlschlägt.

Charles Stewart
quelle
1
Der vorgeschlagene Code df -P $ path | tail -1 | awk '{print $ NF}' schlägt bei allen Solaris-Versionen fehl (2.5.1, 8, 9 und 10), da Solaris 'df' die Option -P nicht unterstützt.
Peter John Acklam
@ Peter: Ich bin weniger erfreut, als ich gedacht hätte. Aber es ist interessant zu wissen, dass das Problem nicht trivial ist. Ich denke, das Richtige ist, einen Befehl in einer Skriptsprache zu schreiben, deren Bibliothek das Problem richtig gelöst hat, z. B. hat Python die Funktion os.path.splitunc (), die den Mount-Punkt angibt und von der ich annehme, dass sie unter Solaris funktioniert.
Charles Stewart
@CharlesStewart: Leider gibt es in Python meines Wissens keine solche Funktion. os.path.splitunc()Funktioniert nur für UNC-Pfade und ist nur unter Windows verfügbar .
Aleksi Torhamo