Дайте точку монтирования пути - PullRequest
13 голосов
/ 30 января 2010

Следующий, очень ненадежный код оболочки даст точку монтирования $path:

 (for i in $(df|cut -c 63-99); do case $path in $i*) echo $i;; esac; done) | tail -n 1

Есть ли лучший способ сделать это в оболочке?

Постскриптум

Этот скрипт действительно ужасен, но обладает таким качеством, что он работает на моих системах. Обратите внимание, что несколько точек монтирования могут иметь префиксы $path.

Примеры В системе Linux:

cas@txtproof:~$ path=/sys/block/hda1
cas@txtproof:~$ 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.

Ответ Похоже, что табличный вывод - единственный путь в оболочке, но

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

на основании ответа ghostdog74, это большое улучшение по сравнению с тем, что у меня было. Обратите внимание на две новые проблемы: во-первых, df $path настаивает на том, что $path называет существующий файл, сценарий, который у меня был выше, не заботится; во-вторых, не стоит беспокоиться о разыменовании символических ссылок. Это не работает, если у вас есть точки монтирования с пробелами в них, что происходит, если у вас есть съемный носитель с пробелами в именах томов.

Нетрудно написать код Python для правильного выполнения работы.

Ответы [ 11 ]

17 голосов
/ 30 января 2010

df принимает путь в качестве параметра, поэтому что-то вроде этого должно быть довольно устойчивым;

df "$path" | tail -1 | awk '{ print $6 }'
14 голосов
/ 30 января 2010

Теоретически stat скажет вам, на каком устройстве находится файл, и должен быть какой-то способ сопоставления устройства с точкой монтирования.

Например, в Linux это должно работать:

stat -c '%m' $path
6 голосов
/ 16 января 2014

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

df --output=target "$path" | tail -1

К сожалению, я не вижу возможности предотвратить печать заголовка, поэтому хвост все еще требуется.

1 голос
/ 30 января 2010

Я бы взял исходный код для df и выяснил, что он делает, кроме вызова stat, как предлагает Дуглас Лидер.

Строковый анализ вывода df вызовет проблемы, так как эти строки часто выглядят как

/dev/mapper/VOLGROUP00-logical--volume
                      1234567  1000000  200000  90% /path/to/mountpoint

С добавленной сложностью синтаксического анализа и таких линий, возможно, вызов stat и поиск точки монтирования менее сложны.

1 голос
/ 30 января 2010

Я не знаю, какой у вас желаемый результат, поэтому это предположение

#!/bin/bash

path=/home
df | awk -v path="$path" 'NR>1 && $NF~path{
 print $NF
}'

Использование cut с -c не совсем надежно, поскольку вывод df будет другим, скажем, 5% может измениться на 10%, и вы пропустите некоторые символы. Поскольку точка монтирования всегда находится сзади, вы можете использовать поля и разделители полей. В приведенном выше примере $ NF - это последний столбец, который является точкой монтирования.

0 голосов
/ 14 марта 2014

Если вы хотите использовать только df и awk для поиска устройства / удаленного общего ресурса файловой системы или точки монтирования, и они содержат пробелы, вы можете обмануть, определив разделитель полей в awk как регулярное выражение, соответствующее формату числового значения размеры, используемые для отображения общего размера, используемого пространства, доступного пространства и процента емкости. Определив эти столбцы в качестве разделителя полей, вы получите $1, представляющий устройство / удаленный общий ресурс файловой системы, и $NF, представляющий путь монтирования.

Возьмем для примера:

[root@testsystem ~] 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 использовать четыре столбца числовых данных в качестве разделителя полей.

[root@testsystem ~] 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

[root@testsystem ~] 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, но должны работать практически с любым дистрибутивом.

0 голосов
/ 11 февраля 2014
f () { echo $6; }; f $(df -P "$path" | tail -n 1)
0 голосов
/ 15 января 2014

Linux имеет это, что позволит избежать проблем с пробелами:

lsblk -no MOUNTPOINT ${device}

Не уверен насчет земли BSD.

0 голосов
/ 08 января 2014

Я использую это:

df -h $path | cut -f 1 -d " " | tail -1
0 голосов
/ 31 января 2010

Я пропустил это, когда просматривал предыдущие вопросы: Python: Получить точку монтирования в Windows или Linux , которая говорит, что os.path.ismount(path) сообщает, является ли путь точкой монтирования. 1006 *

Я предпочитаю решение для оболочки, но это выглядит довольно просто.

...