14

以下非常不可靠的 shell 代码将给出 的挂载点$path

(for i in $(df|cut -c 63-99); do case $path in $i*) echo $i;; 经社理事会;完成)| 尾-n 1

有没有更好的方法在 shell 中做到这一点?

后记

这个脚本真的很糟糕,但它具有可在我的系统上运行的可取之处。请注意,几个挂载点可能是$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;; 经社理事会;完成| 尾-1
/系统

在 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;; 经社理事会;完成| 尾-1
/dev

注意需要改变 cut 的参数,因为 df 的输出方式不同;使用 awk 解决了这个问题,但即使 awk 也是不可移植的,考虑到结果格式化各种 df 返回实现的范围。

答案 看起来修改表格输出是 shell 中的唯一方法,但是

df -P "$path" | 尾-1 | awk '{ 打印 $NF}'

基于ghostdog74的回答,是对我所拥有的一个很大的改进。注意两个新问题:首先,df $path坚持$path命名现有文件,我上面的脚本并不关心;其次,不用担心取消引用符号链接。如果您的挂载点中有空格,这将不起作用,如果一个可移动媒体的卷名中有空格,则会发生这种情况。

编写 Python 代码来正确完成这项工作并不难。

4

12 回答 12

21

df将路径作为参数,所以这样的东西应该相当健壮;

df "$path" | tail -1 | awk '{ print $6 }'
于 2010-01-30T10:48:55.580 回答
16

理论上stat会告诉您文件所在的设备,并且应该有某种方法可以将设备映射到挂载点。

例如,在 linux 上,这应该可以工作:

stat -c '%m' $path
于 2010-01-30T11:41:13.193 回答
7

一直喜欢使用程序的格式化选项,因为它比操作输出更健壮(例如,如果挂载点有空格)。GNUdf允许:

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

不幸的是,我看不到阻止打印标题的选项,因此仍然需要尾部。

于 2014-01-16T18:12:49.810 回答
1

我不知道你想要的输出是什么,因此这是一个猜测

#!/bin/bash

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

使用 cut 和 -c 并不是很可靠,因为 df 的输出会有所不同,例如 5% 可以更改为 10% 并且您会错过一些字符。由于挂载点始终位于后面,因此您可以使用字段和字段分隔符。在上面,$NF 是挂载点的最后一列。

于 2010-01-30T10:42:55.667 回答
1

我会将源代码带到 df 并找出它除了stat像 Douglas Leeder 建议的那样调用之外还做了什么。

输出的逐行解析df会导致问题,因为这些行通常看起来像

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

由于解析这些行也增加了复杂性,调用stat和查找挂载点可能不那么复杂。

于 2010-01-30T12:08:05.983 回答
1

如果您只想使用 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,但应该适用于几乎任何发行版。

于 2014-03-14T00:27:26.423 回答
1

刚遇到同样的问题。如果某个挂载点(或已挂载的设备)就我而言就足够了,您可以这样做:

DEVNO=$(stat -c '%d' /srv/sftp/testconsumer)
MP=$(findmnt -n -f -o TARGET /dev/block/$((DEVNO/2**8)):$((DEVNO&2**8-1)))

(或将十六进制 DEVNO 拆分%D/dev/block/$((0x${DEVNO:0:${#DEVNO}-2})):$((0x${DEVNO:2:2}))

或者,我想到了以下循环,不知道为什么我找不到合适的基本命令..

TARGETPATH="/srv/sftp/testconsumer"
TARGETPATHTMP=$(readlink -m "$TARGETPATH")
[[ ! -d "$TARGETPATHTMP" ]] && TARGETPATHTMP=$(dirname "$TARGETPATH")
TARGETMOUNT=$(findmnt -d backward -f -n -o TARGET --target "$TARGETPATHTMP")
while [[ -z "$TARGETMOUNT" ]]
do
  TARGETPATHTMP=$(dirname "$TARGETPATHTMP")
  echo "$TARGETPATHTMP"
  TARGETMOUNT=$(findmnt -d backward -f -n -o TARGET --target "$TARGETPATHTMP")
done

这应该总是有效,但比我对如此简单任务的期望要多得多?

(编辑使用readlink -f以允许不存在的文件,如果可能不存在更多组件或所有组件必须存在,则可以使用 -m 或 -e 来代替 readlink。)

于 2019-12-01T22:38:57.537 回答
0
mount | grep "^$path" | awk '{print $3}'
于 2010-01-30T14:32:16.783 回答
0

当我查看之前的问题时,我错过了这一点:Python: Get Mount Point on Windows or Linux,它说os.path.ismount(path)告诉路径是否是一个安装点。

我更喜欢 shell 解决方案,但这看起来很简单。

于 2010-01-31T11:00:45.270 回答
0

我用这个:

df -h $path | cut -f 1 -d " " | tail -1
于 2014-01-08T19:39:30.540 回答
0

Linux有这个,这将避免空格问题:

lsblk -no MOUNTPOINT ${device}

不确定BSD土地。

于 2014-01-15T03:44:24.533 回答
0
f () { echo $6; }; f $(df -P "$path" | tail -n 1)
于 2014-02-11T17:57:07.183 回答