No * nix, como determinar em qual sistema de arquivos está um arquivo específico?

12

Em um ambiente unix moderno e genérico (por exemplo, GNU / Linux, GNU / Solaris ou Mac OS X), existe uma boa maneira de determinar em qual ponto de montagem e tipo de sistema de arquivos está o caminho absoluto de um arquivo?

Suponho que eu poderia executar o mountcomando e analisar manualmente a saída disso e compará-lo com o caminho do arquivo, mas antes de fazer isso, fico imaginando se há uma maneira mais elegante.

Estou desenvolvendo um script BASH que utiliza atributos estendidos e quero fazê-lo fazer a coisa certa (na menor extensão possível) para uma variedade de sistemas de arquivos e ambientes host.

smokris
fonte

Respostas:

19

O comando df(1)usa um ou mais argumentos e retornará o ponto de montagem e o dispositivo em que esse arquivo ou diretório existe, além de informações de uso. Você pode usar o caminho ou o dispositivo para procurar o tipo de sistema de arquivos na saída mount -vou similar.

Infelizmente, o formato de saída de ambos dfe mountdepende do sistema; não há um padrão aparente, pelo menos como posso ver entre Solaris, NetBSD e Mac OS X.

Morven
fonte
1
df -Pdeve produzir saída padronizada em qualquer sistema compatível com POSIX. Alguns sistemas mais bobos podem exigir que uma variável de ambiente mágica, como POSIXLY_CORRECT, também seja definida.
Dan Molding
Exemplo df /path-to-the-directorylhe dará a partição que contém daquele diretório
Hasanuzzaman Sattar
7

Você poderia usar stat . O comando stat --printf '% d' filename.txt retornará o número do dispositivo como hexadecimal / decimal.

Zoredache
fonte
Então, como encontrar o nome do dispositivo com base nisso?
Daisy5 /
Você precisa procurar todos os arquivos do dispositivo em / dev / e procurar um com o mesmo número menor que o stat relatado.
Wiesław Herr
stat --printf "%d"informa o número menor de um dispositivo, mas há mais trabalho a ser feito para obter o nome do dispositivo e seu sistema de arquivos montado.
Craig McQueen
2
Talvez seja uma adição recente, mas stat --format '%m' $filefornecerá o ponto de montagem e stat --file-system --format '%T' $mountfornecerá o nome do tipo de sistema de arquivos.
roaima
1
@ TomHale: não se lembre, para ser sincero. Mas eu lembro que não funcionou. É certo que eu deveria ter declarado a distribuição, a versão do kernel etc. Mas você afirma que funciona, também pode significar que foi corrigida enquanto isso. Se o resultado líquido é que ele funciona, ótimo :)
0xC0000022L
3

Para apenas um arquivo específico, é tão fácil quanto

df -T "${FILE}" | awk '{print $2}' | tail -n1
Julian Pawlowski
fonte
Não funciona com btrfs!
0xC0000022L
2

Hum. Para o ponto de montagem, você pode subir a hierarquia até que o st_dev mude (então você acabou de cruzar um limite de montagem); existe o GNU statpara scripts bash; no entanto, não sei como você pode adivinhar o tipo de sistema de arquivos sem analisar /proc/mountsou por tentativa e erro (ou seja, lidar com falhas após definir atributos estendidos)

ΤΖΩΤΖΙΟΥ
fonte
2

Uma dica para o uso dfé que, se o nome do dispositivo na saída for longo, a linha será quebrada, assim você não poderá simplesmente pegar a última linha. Em vez disso, retire a primeira linha, pegue a nova primeira linha e imprima o primeiro campo:

#!/usr/bin/env bash

path=$1
curdir=$(pwd)
cd $path
df . | tail -n +2 | head -1 | awk '{print $1}'
cd $curdir
mage2k
fonte
3
Evite esse problema usando 'df -P' para obter saída no formato POSIX e sem quebra de linha.
MikeyB 22/12/2009
2

Parece haver uma pegadinha com df e btrfs no Linux. Quando você pede ao df para localizar o ponto de montagem de um volume btrfs montado, ele fará a coisa certa. Nesse caso, joe é um subdiretório 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

Mas se o diretório que está sendo referenciado for um subvolume, ele não informará mais o ponto de montagem.

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

O / a / whale / backup é o único ponto de montagem de acordo com o kernel.

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

FWIW, stat faz a mesma coisa:

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

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

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

funciona em qualquer lugar que eu testei, para * BSDs e sysVs e para diretórios malucos montados automaticamente. Eu ficaria feliz em ouvir um caso em que ele falha.

Charles Stewart
fonte
1
O código sugerido df -P $ path | cauda -1 | O awk '{print $ NF}' falha em todas as versões do Solaris que eu tentei (2.5.1, 8, 9 e 10) porque o “df” do Solaris não suporta a opção “-P”.
Peter John Acklam
@ Peter: Estou menos feliz do que pensei que seria. Mas é interessante saber que o problema não é trivial. Eu acho que o certo é escrever um comando em uma linguagem de script cuja biblioteca tenha resolvido o problema corretamente, por exemplo, o Python tem a função os.path.splitunc () que fornece o ponto de montagem e, presumo, funciona no Solaris.
Charles Stewart
@CharlesStewart: Infelizmente, não existe essa função no Python para o meu conhecimento. os.path.splitunc()funciona apenas para caminhos UNC e está disponível no Windows .
Aleksi Torhamo 12/12