确定目录位于什么设备上


49

如果我做

# cd /
# ln -s /home test
# cd test
# mount --bind $PWD /mnt

的条目/proc/mounts

/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0

这是安装在/home且无法轻易推断出$PWD的设备/test/proc/mounts考虑到绑定安装可能是符号链接,其他绑定安装等可能“遮盖”的目录/文件,我如何确定一般将显示哪个设备(即/ dev / sda2)?

Answers:


49

如果我理解您的问题,那么您想知道给定安装使用了哪个设备。为此,您可以使用以下df命令:

$ df -h 
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/fedora_greeneggs-root   50G   21G   27G  44% /
devtmpfs                           3.8G     0  3.8G   0% /dev
tmpfs                              3.8G   14M  3.8G   1% /dev/shm
tmpfs                              3.8G  984K  3.8G   1% /run
tmpfs                              3.8G     0  3.8G   0% /sys/fs/cgroup
tmpfs                              3.8G  3.4M  3.8G   1% /tmp
/dev/sda1                          477M   99M  349M  23% /boot
/dev/mapper/fedora_greeneggs-home  402G  184G  198G  49% /home

要查找在哪个设备上找到特定文件/目录,请将文件作为参数提供给df。使用您的示例:

$ df -h /mnt
Filesystem                         Size  Used Avail Use% Mounted on
/dev/sda1                          477M   99M  349M  23% /

您还可以使用以下mount命令:

$ mount | grep '^/dev'
/dev/mapper/fedora_greeneggs-root on / type ext4 (rw,relatime,seclabel,data=ordered)
/dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
/dev/mapper/fedora_greeneggs-home on /home type ext4 (rw,relatime,seclabel,data=ordered)

为每个设备安装的目录是上面输出中的第三个参数。因此,对于设备/dev/sda1/boot。其他设备正在使用LVM(逻辑卷管理),需要进一步查询以了解LVM正在使用哪个实际设备。


如果$PWD(我正在安装的)被埋在一系列符号链接,绑定安装等中,那么我将需要递归检查安装点的路径。
StrongBad 2014年

尽管在绑定的安装中出现/proc/mounts了“事物”,但至少在我看来,绑定安装不是设备,而是目录/文件。
2014年

@StrongBad- readlink -f /mnt显示什么?
slm

2
@StrongBad如果在符号链接遮盖住时必须处理确定安装点/设备,则应将其放在您的问题中。这样可以更轻松地获得正确的答案。
帕特里克(Patrick)2014年

readlink -f /mnt/mnt
StrongBad 2014年

29

在Linux上,我们正是为此findmnt而来的util-linux

findmnt -n -o SOURCE --target /path/to/FILE

其他解决方案的优点在于,如果路径被符号链接或重复的绑定安装遮盖,它仍然可以正常工作。


这对我不起作用。它显示了系统上每个安装的来源。来自util-linux 2.23.2的findmnt
bwduncan

@bwduncan对我来说适用于2.23.2。也许是个错误?您可以尝试使用最新版本2.29.2吗?
rudimeier

Ubuntu上的2.29可以解决问题。这样不是错误,而是一个功能:)
bwduncan

1
谢谢!这正是我需要的系统脚本。
vog

11

我知道的最准确的方法是使用lstat()系统调用的输出。具体来说,是st_dev字段。有一个命令行实用程序stat(1)可用于查看此信息。例如,我的笔记本电脑上的“ stat / etc / issue”输出为:

File: ‘/etc/issue’
  Size: 65          Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 1610916043  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

注意第三行,第一个字段“ Device”。它列出了801h。该值可以分为两个字节,8和1。第一个字节称为主数字,第二个字节为次数字。因此,下一步是弄清哪个设备主要8是次要1。

我发现咨询/ proc / partitions是最快的。就我而言,/ proc / partitions具有以下内容:

major minor  #blocks  name

   8       16  234431064 sdb
   8       17   33554432 sdb1
   8       18  200875608 sdb2
   8        0  500107608 sda
   8        1  500106584 sda1

从输出中可以很清楚地看出,大8,小1是sda1。我们可以通过ls -l / dev / sda1来确认

brw-rw---- 1 root disk 8, 1 May  8 05:33 /dev/sda1

请注意日期戳之前的8、1。

重要的是要了解/记住像/ dev / sda1这样的设备文件的名称只是一个标签。主要和次要数字是设备文件的重要重要值。如果您感到好奇,请查看用于创建设备文件的mknod(1)实用程序。我可以使用以下语法创建一个名为aardvark的新的/ dev条目,该条目具有主8,辅18。

mknod /dev/aardvark b 8 18

然后,我可以轻松地安装它:

mount /dev/aardvark /mnt

并且,如果我们查看mount命令的输出或/ proc / mounts的内容,则会看到:

/dev/aardvark on /mnt type xfs (rw,relatime,attr2,inode64,noquota)

df -h显示:

/dev/aardvark   192G  154G   38G  81% /mnt

...总之,所有这些的目的是说明识别块设备的重要细节是主要和次要数字-而不是设备文件标签-并且使用lstat()系统调用是实现此目的的最佳方法查询这些值。

作为最后的评论,我只是重新阅读了您的问题,以确保我在回答它,并且我意识到您正在询问要在/ proc / mounts中显示哪个源设备标签进行绑定安装。这将与原始mount(2)调用中用于绑定安装的文件系统安装点源所使用的源设备标签相同。也许一个例子会有所帮助:

我有/ dev / sdb2和/ dev / aardvark(与上面相同)。它们都是主要8个,次要18个。注意,我将两次装载相同的文件系统。我执行以下操作:

mkdir /mnt1 /mnt2 /foo

mount /dev/aardvark /mnt1
mount /dev/sdb2 /mnt2

请注意,我在/ mnt1中将目录设置为somedir。但是,由于/ mnt1和/ mnt2挂载了相同的文件系统,因此也可以通过/ mnt2访问somedir。

mkdir /mnt1/somedir

mkdir /foo/left /foo/right

mount -o bind /mnt1/somedir /foo/left
mount -o bind /mnt2/somedir /foo/right

现在,如果我们检查/ proc / mounts,我们将看到:

/dev/aardvark /mnt1 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /mnt2 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/aardvark /foo/left xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /foo/right xfs rw,relatime,attr2,inode64,noquota 0 0

/ foo / ...绑定安装上的源设备标签与文件系统mount(2)调用中最初提供的值相同。请记住,在我的示例中,/ dev / aardvark和/ dev / sdb2是同一设备。

我意识到我只是写了一本小说,而上半部并没有真正回答您的问题,但是删除它似乎很浪费。也许会帮助别人。

祝好运。

PS请记住,某些文件系统是基于网络的(例如NFS或CIFS),或者是虚拟的(例如procfs或sysfs),并且没有源块设备。我不知道该设备将在stat输出中返回什么,仅仅是它的价值。


1
第一部分肯定可以帮助我理解最后一部分。
StrongBad 2014年

此答案不适用于tmpfs路径。您不会在/ proc / partitions上找到主要的st_dev次要版本。
mbello

@mbello正如我在答案末尾提到的那样,该方法不适用于没有备份设备的文件系统,例如tmpfs挂载。
etherfish

2

给定以下典型安装点:

$ df --output=target
Mounted on
/
/dev
/run
/sys/fs/cgroup
/run/lock
/run/shm
/run/user

stat --format %m <path> 将以可轮换的方式仅打印安装点(尽管您需要检查退出代码以明确检测到权限错误;安装表方法在此处获胜):

$ stat --format %m /
/
$ stat --format %m /tmp
/
$ stat --format %m /proc
/proc
$ stat --format %m /run
/run
$ stat --format %m /run/mount
/run
$ stat --format %m /run/user
/run/user
$ stat --format %m /run/user/1000/dconf
/run/user
$ stat --format %m /run/user/1000/gvfs
/run/user/1000/gvfs

符号链接照常注意:

$ ls -lh ~/.gvfs
/home/cwillu/.gvfs -> /run/user/1000/gvfs
$ stat --format %m ~/.gvfs
/run/user/1000/gvfs
$ stat --format %m ~/.gvfs
/

当然,请记住在编写脚本时要使用引号。考虑带有空格的安装点路径,例如:

$ mkdir /tmp/Something\ Like\ This\!
$ sudo mount none /tmp/Something\ Like\ This\! -t tmpfs
$ stat --format %m /tmp/Something\ Like\ This\!
/tmp/Something Like This!
$ touch /tmp/Something\ Like\ This\!/pretend-I\'m-big
$ ls /tmp/Something\ Like\ This\!
pretend-I'm-big

有多大你吗?

$ du $(stat --format %m /tmp/Something\ Like\ This\!/)
du: cannot access /tmp/Something: No such file or directory
du: cannot access Like: No such file or directory
du: cannot access This!: No such file or directory

$ du "$(stat --format %m /tmp/Something\ Like\ This\!/)"
0   /tmp/Something Like This!

我的发行版的制表符补全甚至没有得到正确的解决,因此我们仅将这个示例挂载点与回车符,换行符和空格运行通配:

$ stat --format %m /tmp/Something*
/tmp/Something   
Like   This!

$ a="$(stat --format %m /tmp/Something*)"
    # the above assignment is actually the one place you don't need quotes, 
    # but `export a=...` or similar _would_ need them, so we'll just put them in;
    # they don't change the behaviour in this form of assignment.

$ stat "$a"
  File: ‘/tmp/Something   \r\n\rLike   This!’
  Size: 40          Blocks: 0          IO Block: 4096   directory
Device: 7bh/123d    Inode: 1279171     Links: 2
Access: (1777/drwxrwxrwt)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-09-30 11:43:17.933467344 -0600
Modify: 2016-09-30 11:43:17.933467344 -0600
Change: 2016-09-30 11:43:17.933467344 -0600
 Birth: -

1
<kbd>标记用于单个键,而不是整个命令。以我的拙见,这种方式看起来并没有任何改善。
Tomasz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.