En * nix, ¿cómo determinar en qué sistema de archivos se encuentra un archivo en particular?

12

En un entorno genérico y moderno de Unix (por ejemplo, GNU / Linux, GNU / Solaris o Mac OS X), ¿hay una buena manera de determinar en qué punto de montaje y tipo de sistema de archivos se encuentra una ruta de archivo absoluta particular?

Supongo que podría ejecutar el mountcomando y analizar manualmente la salida de eso y compararlo con la ruta de mi archivo, pero antes de hacerlo me pregunto si hay una forma más elegante.

Estoy desarrollando un script BASH que hace uso de atributos extendidos y quiero que haga lo correcto (en la medida de lo posible) para una variedad de sistemas de archivos y entornos host.

smokris
fuente

Respuestas:

19

El comando df(1)toma uno o más argumentos y devolverá el punto de montaje y el dispositivo en el que existe ese archivo o directorio, así como la información de uso. Luego puede usar la ruta o el dispositivo para buscar el tipo de sistema de archivos en la salida de mount -vo similar.

Desafortunadamente, el formato de salida de ambos dfy mountdepende del sistema; no hay un estándar aparente, al menos como puedo ver entre Solaris, NetBSD y Mac OS X.

Morven
fuente
1
df -Pdebería producir resultados estandarizados en cualquier sistema compatible con POSIX. Algunos sistemas más tontos pueden requerir una variable de entorno mágico, como POSIXLY_CORRECT, para configurarse también.
Dan Molding el
El ejemplo df /path-to-the-directoryle dará la partición que contiene ese directorio
Hasanuzzaman Sattar el
7

Podrías usar stat . El comando stat --printf '% d' filename.txt devolverá el número del dispositivo como hexadecimal / decimal.

Zoredache
fuente
Entonces, ¿cómo encontrar la base del nombre del dispositivo en eso?
margarita
Debe revisar todos los archivos del dispositivo en / dev / y buscar uno con el mismo número menor que el informe estadístico.
Wiesław Herr
stat --printf "%d"le indica el número menor de un dispositivo, pero hay más trabajo por hacer para obtener el nombre del dispositivo y su sistema de archivos montado.
Craig McQueen
2
Tal vez sea una adición reciente, pero stat --format '%m' $filele dará el punto de montaje y stat --file-system --format '%T' $mountle proporcionará el nombre del tipo de sistema de archivos.
roaima
1
@TomHale: no recuerdo, para ser honesto. Pero recuerdo que no funcionó. Es cierto que debería haber indicado la distribución, la versión del kernel, etc. Pero decir que funciona, también puede significar que se solucionó mientras tanto. Si el resultado neto es que funciona, genial :)
0xC0000022L
3

Solo por un archivo específico es tan fácil como

df -T "${FILE}" | awk '{print $2}' | tail -n1
Julian Pawlowski
fuente
¡No funciona con btrfs!
0xC0000022L
2

Hm. Para el punto de montaje, puede subir la jerarquía hasta que cambie st_dev (luego acaba de cruzar un límite de montaje); hay GNU statpara scripts de bash; sin embargo, no sé cómo puede adivinar el tipo de sistema de archivos sin analizar /proc/mountso por prueba y error (es decir, manejar fallas después de establecer atributos extendidos)

ΤΖΩΤΖΙΟΥ
fuente
2

Un problema con el uso dfes que si el nombre del dispositivo en la salida es largo, su línea se ajustará, por lo que no puede tomar la última línea. En su lugar, elimine la primera línea y luego tome la nueva primera línea y luego imprima el primer campo:

#!/usr/bin/env bash

path=$1
curdir=$(pwd)
cd $path
df . | tail -n +2 | head -1 | awk '{print $1}'
cd $curdir
mage2k
fuente
3
Evite este problema usando 'df -P' para obtener resultados en formato POSIX y sin saltos de línea.
MikeyB
2

Parece que hay un problema con df y btrfs en Linux. Cuando le pide a df que ubique el punto de montaje para un volumen btrfs montado, hará lo correcto. En este caso, Joe es un subdirectorio de / m / whale / backup.

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

Pero si el directorio al que se hace referencia es un subvolumen, ya no le indicará el punto de montaje.

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

El / a / whale / backup es el único punto de montaje según el núcleo.

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

FWIW, stat hace lo mismo:

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

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

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

funciona en todos los lugares que he probado, tanto para * BSD como para sysV y para directorios automáticos extravagantes. Me encantaría saber de un caso en el que falla.

Charles Stewart
fuente
1
El código sugerido df -P $ ruta | cola -1 | awk '{print $ NF}' falla en todas las versiones de Solaris que he probado (2.5.1, 8, 9 y 10) porque 'df' de Solaris no admite la opción "-P".
Peter John Acklam
@ Peter: Estoy menos encantado de lo que pensé que estaría. Pero es interesante saber que el problema no es trivial. Creo que lo correcto es escribir un comando en un lenguaje de secuencias de comandos cuya biblioteca haya resuelto el problema correctamente, por ejemplo, Python tiene la función os.path.splitunc () que proporciona el punto de montaje y que supongo que funciona en Solaris.
Charles Stewart
@CharlesStewart: Lamentablemente, no hay tal función en Python que yo sepa. os.path.splitunc()solo funciona para rutas UNC y solo está disponible en Windows .
Aleksi Torhamo