Ответ 1
df
принимает путь как параметр, поэтому что-то вроде этого должно быть достаточно надежным;
df "$path" | tail -1 | awk '{ print $6 }'
Следующий, очень ненадежный код оболочки даст точку монтирования $path
:
(for i in $(df|cut -c 63-99); do case $path in $i*) echo $i;; esac; done) | tail -n 1
Есть ли лучший способ сделать это в оболочке?
Postscript
Этот script действительно ужасен, но имеет качество погашения, которое он работает в моих системах. Обратите внимание, что несколько точек монтирования могут быть префиксами $path
.
<сильные > Примеры В системе Linux:
[email protected]:~$ path=/sys/block/hda1 [email protected]:~$ for i in $(df -a|cut -c 57-99); do case $path in $i*) echo $i;; esac; done| tail -1 /sys
В системе Mac OSX
cas local$ path=/dev/fd/0 cas local$ for i in $(df -a|cut -c 63-99); do case $path in $i*) echo $i;; esac; done| tail -1 /dev
Обратите внимание на необходимость изменения параметров резки из-за того, как отличается выход df; использование awk решает это, но даже awk не переносится, учитывая диапазон форматирования результата различных реализаций возврата df.
Ответ Похоже, что табулярный вывод munging является единственным способом внутри оболочки, но
df -P "$path" | tail -1 | awk '{ print $NF}'
основанный на ответе ghostdog74, является большим улучшением в отношении того, что у меня было. Обратите внимание на две новые проблемы: во-первых, df $path
настаивает на том, что $path
называет существующий файл, script, который у меня был выше, не волнует; во-вторых, не стоит беспокоиться о разыменовании символических ссылок. Это не работает, если у вас есть точки монтирования с пробелами в них, что происходит, если у вас есть съемные носители с пробелами в их именах томов.
Не сложно написать код Python для правильной работы.
df
принимает путь как параметр, поэтому что-то вроде этого должно быть достаточно надежным;
df "$path" | tail -1 | awk '{ print $6 }'
В теории stat
расскажет вам устройство, в котором находится файл, и должен быть какой-то способ сопоставления устройства с точкой монтирования.
Например, в linux это должно работать:
stat -c '%m' $path
Всегда был поклонником использования опций форматирования программы, поскольку он может быть более надежным, чем манипулирование выводами (например, если точка монтирования имеет пробелы). GNU df
позволяет следующее:
df --output=target "$path" | tail -1
К сожалению, нет возможности, который я могу видеть, чтобы предотвратить печать заголовка, поэтому хвост по-прежнему требуется.
Я не знаю, каков ваш желаемый результат, поэтому это предположение
#!/bin/bash
path=/home
df | awk -v path="$path" 'NR>1 && $NF~path{
print $NF
}'
Использование cut с -c не является действительно надежным, так как вывод df будет другим, скажем, 5% могут измениться на 10%, и вы пропустите некоторые символы. Поскольку точка монтирования всегда находится сзади, вы можете использовать поля и полевые разделители. В приведенном выше случае $NF является последним столбцом, который является точкой монтирования.
Я бы взял исходный код в df и узнал, что он делает, кроме вызова stat
, как предлагает Дуглас Ледер.
Поэтапный анализ вывода df
вызовет проблемы, так как эти строки часто выглядят как
/dev/mapper/VOLGROUP00-logical--volume
1234567 1000000 200000 90% /path/to/mountpoint
С дополнительной сложностью синтаксического анализа этих типов линий, вероятно, вызов stat
и поиск точки монтирования менее сложны.
mount | grep "^$path" | awk '{print $3}'
Я пропустил это, когда просмотрел предыдущие вопросы: Python: получить точку монтирования в Windows или Linux, в которой говорится, что os.path.ismount(path)
указывает, является ли путь точкой монтирования.
Мое предпочтение относится к решению оболочки, но это выглядит довольно просто.
Я использую это:
df -h $path | cut -f 1 -d " " | tail -1
Linux имеет это, что позволит избежать проблем с пробелами:
lsblk -no MOUNTPOINT ${device}
Не уверен относительно земли BSD.
f () { echo $6; }; f $(df -P "$path" | tail -n 1)
Если вы хотите использовать только df и awk, чтобы найти устройство файловой системы/удаленный общий ресурс или точку монтирования, и они включают пробелы, которые вы можете обмануть, указав разделитель полей awk как регулярное выражение, соответствующее формату числового размеры, используемые для отображения общего размера, используемого пространства, свободного пространства и емкости. Определив эти столбцы как разделитель полей, вы остаетесь с $1
, представляющим устройство файловой системы/удаленный общий ресурс, и $NF
, представляющий путь монтирования.
Возьмите это, например:
[[email protected] ~] df -P
Filesystem 1024-blocks Used Available Capacity Mounted on
192.168.0.200:/NFS WITH SPACES 11695881728 11186577920 509303808 96% /mnt/MOUNT WITH SPACES
Если вы попытаетесь разобрать это с помощью быстрого и грязного awk '{print $1}'
или awk '{print $NF}'
, вы получите только часть пути файловой системы/удаленного доступа и путь монтирования, и это не поможет. Теперь сделайте awk использовать четыре столбца числовых данных в качестве разделителя полей.
[[email protected] ~] df -P "/mnt/MOUNT WITH SPACES/path/to/file/filename.txt" | \
awk 'BEGIN {FS="[ ]*[0-9]+%?[ ]+"}; NR==2 {print $1}'
192.168.0.200:/NFS WITH SPACES
[[email protected] ~] df -P "/mnt/MOUNT WITH SPACES/path/to/file/filename.txt" | \
awk 'BEGIN {FS="[ ]*[0-9]+%?[ ]+"}; NR==2 {print $NF}'
/mnt/MOUNT WITH SPACES
Наслаждайтесь: -)
Изменить: эти команды основаны на RHEL/CentOS/Fedora, но должны работать практически с любым распространением.