繁体   English   中英

给出路径的挂载点

[英]Give the mount point of a path

以下非常不健壮的 shell 代码将给出$path的挂载点:

(for i in $(df|cut -c 63-99); do case $path in $i*) echo $i;; esac; done) | tail -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;; 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

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

回答看起来 munging tabular output 是 shell 中的唯一方法,但是

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

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

编写 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
}'

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

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

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

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

由于解析这些类型的行也增加了复杂性,可能调用stat并找到挂载点就不那么复杂了。

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

刚刚有同样的问题。 如果某些挂载点(或已挂载的设备)在我的情况下就足够了,您可以执行以下操作:

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。)

我用这个:

df -h $path | cut -f 1 -d " " | tail -1

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

lsblk -no MOUNTPOINT ${device}

不确定BSD土地。

mount | grep "^$path" | awk '{print $3}'
f () { echo $6; }; f $(df -P "$path" | tail -n 1)

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM