Linux mount (第一部分)

本篇將介紹一些比較實用的mount用法,包括掛載內核中的虛擬文件系統、loop device和bind mount。php

下面的全部例子都在ubuntu-server-x86_64 16.04下執行經過html

基本用法

mount命令的標準格式以下linux

mount -t type -o options device dir
  • device: 要掛載的設備(必填)。有些文件系統不須要指定具體的設備,這裏能夠隨便填一個字符串ubuntu

  • dir: 掛載到哪一個目錄(必填)bash

  • type: 文件系統類型(可選)。大部分狀況下都不用指定該參數,系統都會自動檢測到設備上的文件系統類型oop

  • options: 掛載參數(可選)。
    options通常分爲兩類,一類是Linux VFS所提供的通用參數,就是每一個文件系統均可以使用這類參數,詳情請參考「FILESYSTEM-INDEPENDENT MOUNT OPTIONS」。另外一類是每一個文件系統本身支持的特有參數,這個須要參考每一個文件系統的文檔,如btrfs支持的參數能夠在這裏找到。測試

網上關於如何利用mount命令掛載設備的例子不少,這裏就再也不囉嗦了。spa

掛載虛擬文件系統

proc、tmpfs、sysfs、devpts等都是Linux內核映射到用戶空間的虛擬文件系統,他們不和具體的物理設備關聯,但他們具備普通文件系統的特徵,應用層程序能夠像訪問普通文件系統同樣來訪問他們。code

這裏只是示例一下怎麼掛載他們,不會對他們具體的功能作詳細介紹。server

#將內核的proc文件系統掛載到/mnt,
#這樣就能夠在/mnt目錄下看到系統當前運行的全部進程的信息,
#因爲proc是內核虛擬的一個文件系統,並無對應的設備,
#因此這裏-t參數必需要指定,否則mount就不知道要掛載啥了。
#因爲沒有對應的源設備,這裏none能夠是任意字符串,
#取個有意義的名字就能夠了,由於用mount命令查看掛載點信息時第一列顯示的就是這個字符串。
dev@ubuntu:~$ sudo mount -t proc none /mnt

#在內存中建立一個64M的tmpfs文件系統,並掛載到/mnt下,
#這樣全部寫到/mnt目錄下的文件都存儲在內存中,速度很是快,
#不過要注意,因爲數據存儲在內存中,因此斷電後數據會丟失掉
dev@ubuntu:~$ sudo mount -t tmpfs -o size=64m tmpfs /mnt

掛載 loop device

在Linux中,硬盤、光盤、軟盤等都是常見的塊設備,他們在Linux下的目錄通常是/dev/hda1, /dev/cdrom, /dev/sda1,/dev/fd0這樣的。而loop device是虛擬的塊設備,主要目的是讓用戶能夠像訪問上述塊設備那樣訪問一個文件。 loop device設備的路徑通常是/dev/loop0, dev/loop1, ...等,具體的個數跟內核的配置有關,Ubuntu16.04下面默認是8個,若是8個都被佔用了,那麼就須要修改內核參數來增長loop device的個數。

ISO文件

須要用到loop device的最多見的場景是mount一個ISO文件,示例以下

#利用mkisofs構建一個用於測試的iso文件
dev@ubuntu:~$ mkdir -p iso/subdir01
dev@ubuntu:~$ mkisofs -o ./test.iso ./iso

#mount ISO 到目錄 /mnt
dev@ubuntu:~$ sudo mount ./test.iso /mnt
mount: /dev/loop0 is write-protected, mounting read-only

#mount成功,能看到裏面的文件夾
dev@ubuntu:~$ ls /mnt
subdir01

#經過losetup命令能夠看到佔用了loop0設備
dev@ubuntu:~$ losetup -a
/dev/loop0: []: (/home/dev/test.iso)

虛擬硬盤

loop device另外一種經常使用的用法是虛擬一個硬盤,好比我想嘗試下btrfs這個文件系統,但系統中目前的全部分區都已經用了,裏面都是有用的數據,不想格式化他們,這時虛擬硬盤就有用武之地了,示例以下

#由於btrfs對分區的大小有最小要求,因此利用dd命令建立一個128M的文件
dev@ubuntu:~$ dd if=/dev/zero bs=1M count=128 of=./vdisk.img

#在這個文件裏面建立btrfs文件系統
#有些同窗可能會想,硬盤通常不都是先分區再建立文件系統的嗎?
#是的,分區是爲了方便磁盤的管理,
#但對於文件系統來講,他一點都不關心分區的概念,你給他多大的空間,他就用多大的空間,
#固然這裏也能夠先用fdisk在vdisk.img中建立分區,而後再在分區上建立文件系統,
#只是這裏的虛擬硬盤不須要用做其餘的用途,爲了方便,我就把整個硬盤所有給btrfs文件系統,
dev@ubuntu:~$ mkfs.btrfs ./vdisk.img
#這裏會輸出一些信息,提示建立成功

#mount虛擬硬盤
dev@ubuntu:~$ sudo mount ./vdisk.img /mnt/

#在虛擬硬盤中建立文件成功
dev@ubuntu:~$ sudo touch /mnt/aaaaaa
dev@ubuntu:~$ ls /mnt/
aaaaaa

#加上剛纔上面mount的iso文件,咱們已經用了兩個loop device了
dev@ubuntu:~$ losetup -a
/dev/loop0: []: (/home/dev/test.iso)
/dev/loop1: []: (/home/dev/vdisk.img)

掛載多個設備到一個文件夾

細心的朋友可能已經發現了,在上面的例子中,將test.iso和vdisk.img都mount到了/mnt目錄下,這個在Linux下是支持的,默認會用後面的mount覆蓋掉前面的mount,只有當umount後面的device後,原來的device纔看的到。 看下面的例子

#先umount上面的iso和vdisk.img
dev@ubuntu:~$ sudo umount ./test.iso
dev@ubuntu:~$ sudo umount ./vdisk.img

#在/mnt目錄下先建立一個空的test文件夾
dev@ubuntu:~$ sudo mkdir /mnt/test
dev@ubuntu:~$ ls /mnt/
test

#mount iso文件
dev@ubuntu:~$ sudo mount ./test.iso /mnt
#再看/mnt裏面的內容,已經被iso裏面的內容給覆蓋掉了
dev@ubuntu:~$ ls /mnt/
subdir01

#再mount vdisk.img
dev@ubuntu:~$ sudo mount ./vdisk.img /mnt/
#再看/mnt裏面的內容,已經被vdisk.img裏面的內容給覆蓋掉了
dev@ubuntu:~$ ls /mnt/
aaaaaa

#經過mount命令能夠看出,test.iso和vdisk.img都mount在了/mnt
#但咱們在/mnt下只能看到最後一個mount的設備裏的東西
dev@ubuntu:~$ mount|grep /mnt
/home/dev/test.iso on /mnt type iso9660 (ro,relatime)
/home/dev/vdisk.img on /mnt type btrfs (rw,relatime,space_cache,subvolid=5,subvol=/)

#umount /mnt,這裏也能夠用命令sudo umount ./vdisk.img,同樣的效果
dev@ubuntu:~$ sudo umount /mnt
#test.iso文件裏面的東西再次出現了
dev@ubuntu:~$ ls /mnt/
subdir01

#再次umount /mnt,這裏也能夠用命令sudo umount ./test.iso,同樣的效果
dev@ubuntu:~$ sudo umount /mnt
#最開始/mnt目錄裏面的文件能夠看到了
dev@ubuntu:~$ ls /mnt/
test

有了這個功能,平時掛載設備的時候就不用專門去建立空目錄了,隨便找個暫時不用的目錄掛上去就能夠了。

掛載一個設備到多個目錄

固然咱們也能夠把一個設備mount到多個文件夾,這樣在多個文件夾中均可以訪問該設備中的內容。

#新建兩目錄用於掛載點
dev@ubuntu:~$ sudo mkdir /mnt/disk1 /mnt/disk2
#將vdisk.img依次掛載到disk1和disk2
dev@ubuntu:~$ sudo mount ./vdisk.img /mnt/disk1
dev@ubuntu:~$ sudo mount ./vdisk.img /mnt/disk2

#這樣在disk1下和disk2下面都能看到相同的內容
dev@ubuntu:~$ tree /mnt
/mnt
├── disk1
│   └── aaaaaa
└── disk2
    └── aaaaaa

#在disk1下建立一個新文件
dev@ubuntu:~$ sudo touch /mnt/disk1/bbbbbb
#這個文件在disk2下面也能看到
dev@ubuntu:~$ tree /mnt
/mnt
├── disk1
│   ├── aaaaaa
│   └── bbbbbb
└── disk2
    ├── aaaaaa
    └── bbbbbb

bind mount

bind mount功能很是強大,能夠將任何一個掛載點、普通目錄或者文件掛載到其餘地方,是玩轉Linux的必備技能

基本功能

bind mount會將源目錄綁定到目的目錄,而後在目的目錄下就能夠看到源目錄裏的文件

#準備要用到的目錄
dev@ubuntu:~$ mkdir -p bind/bind1/sub1
dev@ubuntu:~$ mkdir -p bind/bind2/sub2
dev@ubuntu:~$ tree bind
bind
├── bind1
│   └── sub1
└── bind2
    └── sub2

#bind mount後,bind2裏面顯示的就是bind1目錄的內容
dev@ubuntu:~$ sudo mount --bind ./bind/bind1/ ./bind/bind2
dev@ubuntu:~$ tree bind
bind
├── bind1
│   └── sub1
└── bind2
    └── sub1

readonly bind

咱們能夠在bind的時候指定readonly,這樣原來的目錄仍是能讀寫,但目的目錄爲只讀

#經過readonly的方式bind mount
dev@ubuntu:~$ sudo mount -o bind,ro ./bind/bind1/ ./bind/bind2
dev@ubuntu:~$ tree bind
bind
├── bind1
│   └── sub1
└── bind2
    └── sub1

#bind2目錄爲只讀,無法touch裏面的文件
dev@ubuntu:~$ touch ./bind/bind2/sub1/aaa
touch: cannot touch './bind/bind2/sub1/aaa': Read-only file system

#bind1仍是能讀寫
dev@ubuntu:~$ touch ./bind/bind1/sub1/aaa

#咱們能夠在bind1和bind2目錄下看到剛建立的文件
dev@ubuntu:~$ tree bind
bind
├── bind1
│   └── sub1
│       └── aaa
└── bind2
    └── sub1
        └── aaa

若是咱們想讓當前目錄readonly,那麼能夠bind本身,而且指定readonly參數:

#bind mount而且指定readonly
dev@ubuntu:~$ sudo mount -o bind,ro ./bind/bind1/ ./bind/bind1

#建立新文件失敗
dev@ubuntu:~$ touch ./bind/bind1/sub1/aaa
touch: cannot touch './bind/bind1/sub1/aaa': Read-only file system

#umount以後,文件夾恢復到原來的讀寫權限
dev@ubuntu:~$ sudo umount ./bind/bind1/
##touch文件成功
dev@ubuntu:~$ touch ./bind/bind1/sub1/aaa
dev@ubuntu:~$

bind mount單個文件

咱們也能夠bind mount單個文件,這個功能尤爲適合須要在不一樣版本配置文件之間切換的時候

#建立兩個用於測試的文件
dev@ubuntu:~$ echo aaaaaa > bind/aa
dev@ubuntu:~$ echo bbbbbb > bind/bb
dev@ubuntu:~$ cat bind/aa
aaaaaa
dev@ubuntu:~$ cat bind/bb
bbbbbb

#bind mount後,bb裏面看到的是aa的內容
dev@ubuntu:~$ sudo mount --bind ./bind/aa bind/bb
dev@ubuntu:~$ cat bind/bb
aaaaaa

#即便咱們刪除aa文件,咱們仍是可以經過bb看到aa裏面的內容
dev@ubuntu:~$ rm bind/aa
dev@ubuntu:~$ cat bind/bb
aaaaaa

#umount bb文件後,bb的內容出現了,不過aa的內容再也找不到了
dev@ubuntu:~$ sudo umount bind/bb
dev@ubuntu:~$ cat bind/bb
bbbbbb

move一個掛載點到另外一個地方

move操做能夠將一個掛載點移動到別的地方,這裏以bind mount爲例來演示,固然其餘類型的掛載點也能夠經過move操做來移動。

#umount上面操做所產生的掛載點
dev@ubuntu:~$ sudo umount /home/dev/bind/bind1
dev@ubuntu:~$ sudo umount /home/dev/bind/bind2

#bind mount
dev@ubuntu:~$ sudo mount --bind ./bind/bind1/ ./bind/bind2/
dev@ubuntu:~$ ls ./bind/bind*
./bind/bind1:
sub1

./bind/bind2:
sub1

#move操做要求mount point的父mount point不能爲shared。
#在這裏./bind/bind2/的父mount point爲'/',因此須要將'/'變成private後才能作move操做
#關於shared、private的含義將會在下一篇介紹
dev@ubuntu:~$ findmnt -o TARGET,PROPAGATION /
TARGET PROPAGATION
/      shared
dev@ubuntu:~$ sudo mount --make-private /
dev@ubuntu:~$ findmnt -o TARGET,PROPAGATION /
TARGET PROPAGATION
/      private

#move成功,在mnt下能看到bind1裏面的內容
dev@ubuntu:~$ sudo mount --move ./bind/bind2/ /mnt
dev@ubuntu:~$ ls /mnt/
sub1
#因爲bind2上的掛載點已經被移動到了/mnt上,因而能看到bind2目錄下原來的文件了
dev@ubuntu:~$ ls ./bind/bind2/
sub2

結束語

在這篇文章中演示了一些比較實用的mount操做,尤爲是bind mount,至於在哪些狀況下要用哪些功能,須要咱們本身去挖掘。下一篇中將介紹mount相關的「Shared subtrees」

參考

相關文章
相關標籤/搜索