W * nix, jak ustalić, na jakim systemie plików znajduje się dany plik?

12

Czy w ogólnym, nowoczesnym środowisku unixowym (powiedzmy GNU / Linux, GNU / Solaris lub Mac OS X) istnieje dobry sposób, aby ustalić, który punkt montowania i typ systemu plików ma dana absolutna ścieżka do pliku?

Podejrzewam, że mógłbym wykonać mountpolecenie i ręcznie przeanalizować dane wyjściowe i porównać je ze ścieżką pliku, ale zanim to zrobię, zastanawiam się, czy istnieje bardziej elegancki sposób.

Zajmuję się tworzeniem skryptu BASH, który wykorzystuje rozszerzone atrybuty, i chcę, aby działał on właściwie (w niewielkim stopniu, w jakim jest to możliwe) dla różnych systemów plików i środowisk hosta.

smokris
źródło

Odpowiedzi:

19

Polecenie df(1)przyjmuje jeden lub więcej argumentów i zwraca punkt montowania i urządzenie, na którym istnieje ten plik lub katalog, a także informacje o użyciu. Następnie możesz użyć ścieżki lub urządzenia, aby wyszukać typ systemu plików na wyjściu mount -vlub podobny.

Niestety, format wyjściowy zarówno dfi mountsą zależne od systemu; nie ma widocznego standardu, przynajmniej jak widzę między Solaris, NetBSD i Mac OS X.

Morven
źródło
1
df -Ppowinien generować znormalizowane dane wyjściowe w dowolnym systemie zgodnym z POSIX. Niektóre systemy gooferów mogą również wymagać ustawienia magicznej zmiennej środowiskowej, takiej jak POSIXLY_CORRECT.
Dan Molding
Przykład df /path-to-the-directoryda Ci zawierającą partycję tego katalogu
Hasanuzzaman Sattar
7

Możesz użyć statystyki . Polecenie stat --printf '% d' nazwa_pliku.txt zwróci numer urządzenia w postaci szesnastkowej / dziesiętnej.

Zoredache
źródło
Jak znaleźć na tym nazwę urządzenia?
stokrotka
Musisz przejrzeć wszystkie pliki urządzeń w / dev / i wyszukać jeden z tym samym numerem pomocniczym, jak podano w statystykach.
Wiesław Herr
stat --printf "%d"wskazuje mniejszą liczbę urządzeń, ale jest jeszcze wiele do zrobienia, aby uzyskać nazwę urządzenia i zamontowany system plików.
Craig McQueen
2
Być może jest to najnowszy dodatek, ale stat --format '%m' $filepoda punkt montowania i stat --file-system --format '%T' $mountpoda nazwę typu systemu plików.
roaima
1
@TomHale: nie pamiętam, szczerze mówiąc. Ale pamiętam, że to nie działało. Trzeba przyznać, że dystrybucja, wersja jądra itp. Ale stwierdzenie, że działa, może oznaczać, że w międzyczasie zostało naprawione. Jeśli wynik netto jest taki, że to działa, świetnie :)
0xC0000022L
3

W przypadku konkretnego pliku jest to tak proste, jak

df -T "${FILE}" | awk '{print $2}' | tail -n1
Julian Pawłowski
źródło
Nie działa z btrfs!
0xC0000022L
2

Hm Dla punktu montowania możesz iść w górę hierarchii, aż zmieni się st_dev (wtedy właśnie przekroczyłeś granicę montowania); istnieje GNU statdla skryptów bash; nie wiem jednak, jak odgadnąć typ systemu plików bez analizowania /proc/mountslub metodą prób i błędów (tj. obsługi błędów po ustawieniu atrybutów rozszerzonych)

ΤΖΩΤΖΙΟΥ
źródło
2

Jednym z problemów związanych z używaniem dfjest to, że jeśli nazwa urządzenia na wyjściu jest długa, wiersz zostanie zawinięty, więc nie można po prostu pobrać ostatniej linii. Zamiast tego zdejmij pierwszą linię, a następnie chwyć nową pierwszą linię, a następnie wydrukuj pierwsze pole:

#!/usr/bin/env bash

path=$1
curdir=$(pwd)
cd $path
df . | tail -n +2 | head -1 | awk '{print $1}'
cd $curdir
mag2k
źródło
3
Unikaj tego problemu, używając „df -P”, aby uzyskać dane wyjściowe w formacie POSIX i bez łamania linii.
MikeyB,
2

Wydaje się, że w Linuksie istnieje pewien problem z df i btrfs. Gdy poprosisz df o zlokalizowanie punktu montowania zamontowanego woluminu btrfs, zrobi to dobrze. W tym przypadku Joe jest podkatalogiem / m / whale / backup.

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

Ale jeśli katalog, do którego następuje odwołanie, jest pod-woluminem, nie będzie już wskazywać punktu podłączenia.

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

/ A / whale / backup jest jedynym punktem montowania zgodnie z jądrem.

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

FWIW, stat robi to samo:

# stat --printf '%m\n' /srv/backup/joe/code
/a/whale/backup/joe/code
Marc Singer
źródło
1

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

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

działa wszędzie, gdzie testowałem, zarówno dla * BSD i sysV, jak i dla zwariowanych automatycznych katalogów. Z przyjemnością usłyszę o przypadku, w którym się nie powiedzie.

Charles Stewart
źródło
1
Sugerowany kod df -P $ ścieżka | ogon -1 | awk „{print $ NF}” nie działa we wszystkich wersjach Solaris, których wypróbowałem (2.5.1, 8, 9 i 10), ponieważ „df” w Solarisie nie obsługuje opcji „-P”.
Peter John Acklam
@Peter: Jestem mniej zachwycony, niż się spodziewałem. Interesujące jest jednak to, że problem nie jest prosty. Myślę, że właściwą rzeczą jest napisanie polecenia w języku skryptowym, którego biblioteka poprawnie rozwiązała problem, np. Python ma funkcję os.path.splitunc (), która daje punkt montowania i która, jak zakładam, działa w systemie Solaris.
Charles Stewart
@CharlesStewart: Niestety, o ile wiem, w Pythonie nie ma takiej funkcji. os.path.splitunc()działa tylko dla ścieżek UNC i jest dostępny tylko w systemie Windows .
Aleksi Torhamo,