В * nix, как определить, в какой файловой системе находится конкретный файл?

12

В общей современной среде Unix (скажем, GNU / Linux, GNU / Solaris или Mac OS X) существует ли хороший способ определить, к какой точке монтирования и типу файловой системы относится конкретный абсолютный путь к файлу?

Я полагаю, что мог бы выполнить mountкоманду и вручную проанализировать вывод этой строки и сравнить ее со строкой моего пути к файлу, но прежде чем я это сделаю, мне интересно, есть ли более элегантный способ.

Я разрабатываю сценарий BASH, который использует расширенные атрибуты, и хочу, чтобы он делал все правильно (в малой степени, насколько это возможно) для различных файловых систем и хост-сред.

smokris
источник

Ответы:

19

Команда df(1)принимает один или несколько аргументов и возвращает точку монтирования и устройство, на котором существует этот файл или каталог, а также информацию об использовании. Затем вы можете использовать путь или устройство для поиска типа файловой системы в выходных данных mount -vили аналогичных.

К сожалению, формат вывода обоих dfи mountзависит от системы; нет очевидного стандарта, по крайней мере, как я вижу между Solaris, NetBSD и Mac OS X.

Morven
источник
1
df -Pдолжен производить стандартизированный вывод в любой POSIX-совместимой системе. В некоторых глупых системах может потребоваться установка магической переменной среды, такой как POSIXLY_CORRECT.
Дэн Молдинг,
Пример df /path-to-the-directoryдаст вам содержащий раздел этого каталога
Хасануззаман Саттар
7

Вы можете использовать стат . Команда stat --printf '% d' filename.txt вернет номер устройства в шестнадцатеричном / десятичном виде.

Zoredache
источник
Итак, как найти базу имени устройства на этом?
Дейзи
Вам нужно перейти через все файлы устройств в / dev / и найти тот же младший номер, что и в отчете stat.
Веслав Герр
stat --printf "%d"действительно говорит вам младший номер устройства, но еще предстоит проделать дополнительную работу, чтобы получить имя устройства и его смонтированную файловую систему.
Крейг МакКуин
2
Возможно, это недавнее дополнение, но оно stat --format '%m' $fileдаст вам точку монтирования и stat --file-system --format '%T' $mountпредоставит имя типа файловой системы.
Роайма
1
@ TomHale: не помню, если честно. Но я помню, это не сработало. По общему признанию я должен был указать дистрибутив, версию ядра и т. Д. Но вы заявляете, что это работает, может также означать, что это исправлено тем временем. Если чистый результат в том, что он работает, отлично :)
0xC0000022L
3

Для конкретного файла это так же просто, как

df -T "${FILE}" | awk '{print $2}' | tail -n1
Джулиан Павловски
источник
Не работает с btrfs!
0xC0000022L
2

Гектометр Для точки монтирования вы можете идти вверх по иерархии, пока не изменится st_dev (тогда вы только что пересекли границу монтирования); есть GNU statдля скриптов bash; Тем не менее, я не знаю, как вы можете угадать тип файловой системы без разбора /proc/mountsили методом проб и ошибок (т.е. обрабатывать сбои после установки расширенных атрибутов)

ΤΖΩΤΖΙΟΥ
источник
2

Одна проблема с использованием dfзаключается в том, что если имя устройства в выводе длинное, строка будет перенесена, поэтому вы не сможете просто взять последнюю строку. Вместо этого удалите первую строку, а затем возьмите новую первую строку и напечатайте первое поле:

#!/usr/bin/env bash

path=$1
curdir=$(pwd)
cd $path
df . | tail -n +2 | head -1 | awk '{print $1}'
cd $curdir
mage2k
источник
3
Избегайте этой ошибки, используя 'df -P' для получения вывода в формате POSIX и без переноса строки.
MikeyB
2

Кажется, в Linux есть проблема с df и btrfs. Когда вы просите df определить точку монтирования для смонтированного тома btrfs, это будет правильно. В этом случае joe является подкаталогом / m / whale / backup.

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

Но если каталог, на который ссылаются, является вложенным томом, он больше не сообщит вам точку монтирования.

# 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 - единственная точка монтирования в соответствии с ядром.

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

FWIW, stat делает то же самое:

# stat --printf '%m\n' /srv/backup/joe/code
/a/whale/backup/joe/code
Марк Сингер
источник
1

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

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

работает везде, где я тестировал, как для * BSD, так и для sysV, а также для дурацких автоматически монтируемых каталогов. Я был бы рад услышать о случае, когда это терпит неудачу.

Чарльз Стюарт
источник
1
Предлагаемый код df -P $ path | хвост -1 | awk '{print $ NF}' терпит неудачу во всех версиях Solaris, которые я пробовал (2.5.1, 8, 9 и 10), потому что Solaris «df» не поддерживает опцию «-P».
Питер Джон Аклам
@Peter: я менее рад, чем я думал, что буду. Но интересно знать, что проблема нетривиальна. Я думаю, что правильно написать команду на языке сценариев, библиотека которого решила проблему правильно, например, в Python есть функция os.path.splitunc (), которая дает точку монтирования и которая, как я полагаю, работает на Solaris.
Чарльз Стюарт
@CharlesStewart: к сожалению, в Python нет такой функции, насколько мне известно. os.path.splitunc()работает только для путей UNC и доступно только в Windows .
Алекси Торхамо