ディレクトリが配置されているデバイスを特定する


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)が表示されるかを判断するにはどうすればよいですか?

回答:


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)

各デバイスにマウントされるディレクトリは、上記の出力の3番目の引数です。したがって、デバイスの場合/dev/sda1はになります/boot。他のデバイスはLVM(論理ボリューム管理)を使用しているため、LVMが実際に使用しているデバイスを知るためにさらに照会する必要があります。


場合$PWD(これは私が設置していますものですが)シンボリックリンク、バインドマウントなどの直列に埋設されているし、私は再帰的にマウントポイントのパスを検討する必要があります。
StrongBad

/proc/mounts少なくとも私の考えでは、マウントされている「もの」に現れるものにかかわらず、バインドマウントでは、デバイスはディレクトリ/ファイルではありません。
StrongBad

@StrongBad-何がreadlink -f /mnt表示されますか?
slm

2
@StrongBadシンボリックリンクによって不明瞭になったときにマウントポイント/デバイスを決定する必要がある場合は、それを質問に入れてください。正しい答えを得るのがずっと簡単になります。
パトリック

readlink -f /mnt与える/mnt
StrongBad

29

Linuxではfindmntutil-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)

3行目の最初のフィールド「デバイス」に注目してください。ここに801hがリストされています。その値は、8バイトと1バイトの2バイトに分けることができます。最初のバイトはメジャー番号と呼ばれ、2番目のバイトはマイナー番号です。したがって、次のステップは、デバイスメジャー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)ユーティリティを確認してください。次の構文を使用して、メジャー8、マイナー18のaardvarkという新しい/ devエントリを作成できます。

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です。注、同じファイルシステムを2回マウントします。私は次のことを行います:

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

この回答は、tmpfsパスでは機能しません。/ proc / partitionsにst_dev minor、majorは見つかりません。
mbello

@mbello答えの最後で述べたように、この方法は、tmpfsマウントのようなバッキングデバイスのないファイルシステムでは機能せず、機能しません。
エーテルフィッシュ

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>マークアップは、コマンド全体ではなく、単一のキーに使用されます。私の謙虚な意見では、このように良く見えることはありません。
トマス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.