23、磁盘及文件系统详解

23.1 磁盘管理(IO设备):

机械式硬盘:

    Cylinder:柱面

    分区是磁盘的逻辑边界

    磁盘刚出场时进行低级格式化,没有进行分区,创建磁道

    高级格式化:格式化以后可以创建文件系统

    Partition(分区):划分文件系统

    MBR(主引导记录):在零柱面,一般为512字节

        Master Boot Record

        Main Boot Record

                       446bytes:BootLoader,引导程序

                        64bytes:

                              16bytes:表示一个分区

                               前三个可以是主分区,第四个可以是扩展分区(指向其他地方的指针)

                                只能有四个分区,扩展分区只能有一个,扩展分区下的分区称之为是逻辑分区,逻辑分区可以有多个

                        2bytes:Magic Number

                              标记MBR是否有效    

    划分分区按柱面进行划分

    磁盘读写延迟,由硬盘的转速来决定,转速越快性能越好

    硬盘盘芯为真空,因为转速过快,要挡住灰尘,避免高温 

    文件系统是个管理软件,将磁盘划分为元数据(定义数据的编号和位置)和数据存储区

    位图(bitmap):

        用来确认存储空间使用情况的文件

             分为Inode bitmap和block bitmap

    Inode(Index Node):

        索引节点,存储和文件内容无关的文件信息

地址指针:

直接指针:

间接指针:

三级指针:

[root@localhost ~]# dumpe2fs /dev/sdb1 | tail -10

dumpe2fs 1.42.9 (28-Dec-2013)

  Inode table at 2080771-2080898 (+2)

  8059 free blocks, 492 free inodes, 3 directories

  Free blocks: 2080902-2088960

  Free inodes: 130069-130560

Group 255: (Blocks 2088961-2097151)

  Block bitmap at 2088961 (+0), Inode bitmap at 2088962 (+1)

  Inode table at 2088963-2089090 (+2)

  8061 free blocks, 512 free inodes, 0 directories

  Free blocks: 2089091-2097151

  Free inodes: 130561-131072

[root@localhost ~]# 

Inode bitmap:对应标识每个inode空闲与否的状态信息

  每个文件系统支持的单个文件的大小是不一样的

    目录:

        存储Inode号码和文件名

    尽可能让磁盘里面的文件使用连续的磁盘块,可以减少磁盘碎片,这样可以提升访问文件的速度

    创建分区会首先创建许多个块组

    块组:

        很多个小的逻辑分区,每个块组都有自己的块位图,Inode位图等信息

    Super block:

             保存全局信息,块组信息,inode信息

    block(块):一个大小一般为1024(1K),有的也为,2048(2K)或4096(4K)

    固态硬盘、U盘、光盘、软盘、硬件、磁带

23.2 链接文件

    链接文件:分为硬链接和符号连接

/etc/abc --à/usr/local/abc

    ln [-s -v] SRC DEST

-s代表软连接,不带任何选项代表硬链接,

-v(verbose)代表显示创建过程

    硬链接:直接指向同一个Inode的不同路径

    硬链接:

        1、只能对文件创建,不能应用于目录;

        2、不能跨文件系统;

        3、创建硬链接会增加文件被链接的次数(指向同一个inode的多个不同路径);

    符号连接:直接指向另一个文件的文件路径   

    符号链接:

        1、可应用于目录;

        2、可以跨文件系统,跨分区进行;

        3、不会增加被链接文件的链接次数;

        4、指向的是另一个文件的路径,其大小为指定的路径所包含的字符个数;

[root@localhost ~]# ln anaconda-ks.cfg a

[root@localhost ~]# ls -a

.   a                .bash_history  .bash_profile  .cshrc             .tcshrc

..  anaconda-ks.cfg  .bash_logout   .bashrc        .oracle_jre_usage  .viminfo

[root@localhost ~]# ll

total 8

-rw-------. 2 root root 1426 May 27 06:31 a

-rw-------. 2 root root 1426 May 27 06:31 anaconda-ks.cfg

[root@localhost ~]# ls -li

total 8

100663375 -rw-------. 2 root root 1426 May 27 06:31 a

100663375 -rw-------. 2 root root 1426 May 27 06:31 anaconda-ks.cfg

[root@localhost ~]# ln -s anaconda-ks.cfg b

[root@localhost ~]# ll -a

total 40

dr-xr-x---.  3 root root  194 Jul 21 21:46 .

dr-xr-xr-x. 17 root root  224 May 27 06:31 ..

-rw-------.  2 root root 1426 May 27 06:31 a

-rw-------.  2 root root 1426 May 27 06:31 anaconda-ks.cfg

lrwxrwxrwx.  1 root root   15 Jul 21 21:46 b -> anaconda-ks.cfg

-rw-------.  1 root root 4056 Jul 12 01:58 .bash_history

-rw-r--r--.  1 root root   18 Dec 28  2013 .bash_logout

-rw-r--r--.  1 root root  176 Dec 28  2013 .bash_profile

-rw-r--r--.  1 root root  176 Dec 28  2013 .bashrc

-rw-r--r--.  1 root root  100 Dec 28  2013 .cshrc

drwxr-xr-x.  2 root root   40 May 27 06:54 .oracle_jre_usage

-rw-r--r--.  1 root root  129 Dec 28  2013 .tcshrc

-rw-------.  1 root root 6448 May 31 02:46 .viminfo

[root@localhost ~]# ls -li

total 8

100663375 -rw-------. 2 root root 1426 May 27 06:31 a

100663375 -rw-------. 2 root root 1426 May 27 06:31 anaconda-ks.cfg

100663380 lrwxrwxrwx. 1 root root   15 Jul 21 21:46 b -> anaconda-ks.cfg

[root@localhost ~]# 

df :查看磁盘及文件系统占用

-h:human-readable

-i:ibodes instead of blocks

-P:以Posix兼容的格式输出

du:查看某目录总体空间占用状态:

-h:human-readable进行格式转换

-s:summary查看目录整体大小

[root@localhost ~]# df -h

Filesystem               Size  Used Avail Use% Mounted on

/dev/mapper/centos-root   50G  2.6G   48G   6% /

devtmpfs                 3.9G     0  3.9G   0% /dev

tmpfs                    3.9G     0  3.9G   0% /dev/shm

tmpfs                    3.9G  8.7M  3.9G   1% /run

tmpfs                    3.9G     0  3.9G   0% /sys/fs/cgroup

/dev/sda1               1014M  143M  872M  15% /boot

/dev/mapper/centos-home   42G   33M   42G   1% /home

tmpfs                    781M     0  781M   0% /run/user/0

/dev/sdc2                 33M  782K   30M   3% /mydata

[root@localhost ~]# du -h

4.0K    ./.oracle_jre_usage

44K .

[root@localhost ~]# du -sh

44K .

[root@localhost ~]# 

23.3 设备文件:

    b(块设备): 按块为单位,随机访问的设备;

    c(字符设备):按字符为单位,线性设备;

    常见的设备

        b(块设备): 硬盘

        c(字符设备): 键盘

1、位置(/dev)

    [root@Daniel-R480 ~]# ls -lh /dev

    total 0

    drwxr-xr-x 1 root root     4.0K Jun 17 09:19 block

    lrwxrwxrwx 1 root root       13 Jun 17 09:19 fd -> /proc/self/fd

    crw-r--r-- 1 root root   1,  11 Jun 17 09:19 kmsg

    crw-rw-rw- 1 root root  10,  50 Jun 17 09:19 lxss

    crw-rw-rw- 1 root root   1,   3 Jun 17 09:19 null

    crw-rw-rw- 1 root tty    5,   2 Jun 17 09:44 ptmx

    设备文件中间的两个数字为主设备号,次设备号,其无大小,存储主次设备号在inode中

        主设备号 (major number)

            标识设备类型

        次设备号 (minor number)

            标识同一种类型中不同设备

2、mknod(创建设备文件)

mknod [OPTION]... NAME TYPE [MAJOR MINOR]

    -m MODE指定权限

    [root@Daniel-R480 ~]# mknod -m 640 mydev2 c 66 0

    [root@Daniel-R480 ~]# ls -l

    total 32

    lrwxrwxrwx 1 root  root     1 Jun 17 10:42 abc -> a

    -rwxr-xr-x 1 root  root   230 Jun  9 14:50 addusers.sh

    -rwxr-xr-x 1 root  root   591 Jun 16 17:32 adminusers2.sh

    -rwxr-xr-x 1 root  root  1140 Jun 17 09:21 adminusers3.sh

    -rwxr-xr-x 1 root  root   559 Jun  9 15:21 adminusers.sh

    -rw------- 1 root  root  6921 Jan 29  2019 anaconda-ks.cfg

    -rw-r--r-- 1 user2 root     0 Jun  9 17:32 b

    -rw-r--r-- 1 root  root     0 Jun  9 17:32 c

    -rwxr-xr-x 1 root  root   106 Jun  9 10:01 calc.sh

    -rw-r--r-- 1 root  root     0 Jun  9 17:32 d

    -rwxr-xr-x 1 root  root   173 Jun  9 14:55 delusers.sh

    -rwxr-xr-x 1 root  root   158 Jun 16 17:21 list2.sh

    -rwxr-xr-x 1 root  root   127 Jun 16 17:23 list.sh

    crw-r--r-- 1 root  root 66, 0 Jun 17 11:01 mydev

    crw-r----- 1 root  root 66, 0 Jun 17 11:01 mydev2

    -rw------- 1 root  root  6577 Jan 29  2019 original-ks.cfg

    -rwxr-xr-x 1 root  root   250 Jun  9 09:43 quit.sh

    -rwxr-xr-x 1 root  root   562 Jun 17 09:37 showlogged.sh

    -rwxr-xr-x 1 root  root   198 Jun 16 17:31 sys.sh

    -rwxr-xr-x 1 root  root     0 Jun  8 17:50 test

    -rwxr-xr-x 1 root  root    87 Jun  9 10:36 testuser.sh

可以通过设备文件向某个设备直接传输数据

    [root@Daniel-R480 ~]# tty

    /dev/pts/0

    [root@Daniel-R480 ~]# echo hello >>/dev/pts/1

    [root@Daniel-R480 ~]# 

    #另一个终端下

    [root@Daniel-R480 ~]# tty

    /dev/pts/1

    [root@Daniel-R480 ~]# hello

3、硬盘设备的设备文件名:

    设备文件名和硬盘的接口类型有关

    IDE, ATA:hd

    SATA:sd

    SCSI: sd

    USB: sd

        a,b,c,...来区别同一种类型下的不同设备

    IDE: 一般PC机上只有两个IDE口,每个口上可以接两块盘

    分区方案

        第一个IDE口:主、从

                   /dev/hda, /dev/hdb

        第二个IDE口:主、从

                  /dev/hdc, /dev/hdd

    SATA/SCSI/USB分区方案

    sda, sdb, sdc, …

    hda: (IDE硬盘)

        hda1: 第一个主分区

        hda2: 

        hda3:

        hda4:

        hda5: 第一个逻辑分区(只能从hda5开始)

4、fdisk

(1)fdisk -l [/dev/to/some_device_file]

查看当前系统识别了几块硬盘:

[root@localhost dev]# fdisk -l

Disk /dev/sda: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sdb: 107.4 GB, 107374182400 bytes, 209715200 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0x000acbe0

   Device Boot      Start         End      Blocks   Id  System

/dev/sdb1   *        2048     2099199     1048576   83  Linux

/dev/sdb2         2099200   209715199   103808000   8e  Linux LVM

Disk /dev/mapper/centos-root: 53.7 GB, 53687091200 bytes, 104857600 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-swap: 8455 MB, 8455716864 bytes, 16515072 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/nvme0n1: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sdc: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-home: 44.1 GB, 44149243904 bytes, 86228992 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

[root@localhost dev]# 

(2)管理磁盘分区:

fdisk /dev/sda(对于一块硬盘来说,最多只能管理15分区)

    p: 显示当前硬件的分区,包括没保存的改动

    n: 创建新分区

        e: 扩展分区

        p: 主分区

    d: 删除一个分区

    w: 保存退出

    q: 不保存退出

    t: 修改分区类型

        L: 显示所有支持的分区类型

    l: 显示所支持的所有分区类型(在t命令里面用L)

[root@localhost ~]# fdisk /dev/sdc

Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.

Be careful before using the write command.

Command (m for help): p

Disk /dev/sdc: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0x06bd6860

   Device Boot      Start         End      Blocks   Id  System

Command (m for help): n

Partition type:

   p   primary (0 primary, 0 extended, 4 free)

   e   extended

Select (default p): p

Partition number (1-4, default 1): 1

First sector (2048-2097151, default 2048): 2048

Last sector, +sectors or +size{K,M,G} (2048-2097151, default 2097151): 1000000

Partition 1 of type Linux and of size 487.3 MiB is set

Command (m for help): p

Disk /dev/sdc: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0x06bd6860

   Device Boot      Start         End      Blocks   Id  System

/dev/sdc1            2048     1000000      498976+  83  Linux

Command (m for help): w

The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.

The kernel still uses the old table. The new table will be used at

the next reboot or after you run partprobe(8) or kpartx(8)

Syncing disks.

(3)查看内核是否已经识别新的分区

[root@localhost ~]# cat /proc/partitions | grep sdc

   8       32    1048576 sdc

   8       33     498976 sdc1

[root@localhost ~]# 

(4)partx:新版系统常用(通知内核重新读取硬盘分区表)

partx -a /dev/DEVICE

-n M:N(指定开始结束的位置,也可写为M:,:N)

kpartx -a /dev/DEVICE

-f:force(强制添加,风险比较大,尽量不使用)

CentOS 5

partprobe [/dev/device]:也可以用来修改分区 

5、判断文件状态

if [[ ! -s filename ]] <==如果文件存在且为空,-s代表存在不为空,!将他取反

then

ok

fi

-s 表示文件是否存在并且是否为非空

判断文件的参数如下

    -e 文件存在      

    -f file 是一个 regular 文件(不是目录或者设备文件)

    -s 文件长度不为 0

    -d 文件是个目录

    -b 文件是个块设备(软盘,cdrom 等等) 

    -c 文件是个字符设备(键盘,modem,声卡等等) 

     -p 文件是个管道

     -h 文件是个符号链接

    -L 文件是个符号链接

    -S 文件是个 socket

    -t 关联到一个终端设备的文件描述符,这个选项一般都用来检测是否在一个给定脚本中的 stdin[-t0]或[-t1]是一个终端

    -r 文件具有读权限(对于用户运行这个 test) 

     -w 文件具有写权限(对于用户运行这个 test) 

    -x 文件具有执行权限(对于用户运行这个 test)

6、文件操作

文件删除

文件复制

文件移动

练习:写一个脚本

通过命令行传递一个文件路径参数给脚本:

    如果参数多了或少了,报错;

    如果参数指定的路径对应的是目录而不是文件,报错;

而后,检查路径指定的文件是否为空或不存在,如果是,则新建此文件,并在文件中生成如下内容

#!/bin/bash

而后,使用vim编辑器打开此文件,并让光标处于这个文件的最后一行;

写个脚本,按如下方式执行:

mkscript.sh -v|--version VERSION -a|--author AUTHOR -t|--time DATETIME -d|--description DESCRIPTION -f|--file /PATH/TO/FILE -h|--help 

1、此脚本能创建或打开-f选项指向的文件/PATH/TO/FILE;如果其为空文件,能自动为其生成第一行;如果文件不空,且第一行不是#!/bin/bash,则中止此脚本,并报错“The file is not a bash script.";

否则,则直接使用vim 打开此文件;

提示:/PATH/TO/FILE,要判断其目录是否存在;如果不存在,则报错;

2、如果为空文件,自动生成的第一行内容为:

#!/bin/bash

3、如果为空文件,且使用了-a选项,则在文件中添加“# Author: -a选项的参数”,比如:

# Author: Jerry

4、如果为空文件,且使用了-t选项,则在文件中添加“# Date: 脚本执行-t选项后指定的时间”,比如:

# Date: 2013-03-08 18:05

5、如果为空文件,且使用了-d选项,则在文件中添加“# Description: -d选项的内容”,比如:

# Description: Create a bash script file head.

6、如果为空文件,且使用了-v选项,则在文件添加“# Version: -v后跟的参数”,比如:

# Version: 0.1

6、-h选项只能单独使用,用于显示使用帮助;

7、其它选项,显示帮助信息;

说明:

这是一个用于创建脚本的脚本,它可以自动帮助创建一个bash脚本的文件头,这样,以后使用此脚本来创建其它脚本将变得比较高效。比如:

#!/bin/bash

# Author: Jerry(jerry@magedu.com)

# Date: 2013-03-08 18:05

# Description: Create a bash script file head.

# Version: 0.1

#

    #/bin/bash

    #

    #判断FILE是否存在

    FI=0

    #判断FILE是否为空

    FIL=0

    #添加作者

    AUT=0

    #date

    DAT=0

    #description

    DES=0

    #VERSION

    VER=0

    for I in `seq 0 $#`; do

      if [ $# -gt 0 ];then

       case $1 in

         -f|--file)

            FILE=$2

            if [ -e $FILE ];then

                   FI=1

               if [ -s $FILE ];then

                   FIL=1

               fi

            else

               echo -e "$FILE is no exist.\n mkscripts exitting..."

               exit 1

            fi

             shift 2;;

         -a)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then

               AUT=1

               AUTH=$2

            #fi

               shift 2;;

         -t)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then        

               DAT=1

               DATE=$2

            #fi

               shift 2;;

         -d)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then

               DES=1

               DESC=$2

            #fi

               shift 2;;

         -v)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then

               VER=1

               VERS=$2

           #fi

               shift 2;;

         -h)

            echo "Usage is :`basename $0` -v|--version VERSION -a|--author AUTHOR -t|--time DATETIME -d|--description DESCRIPTION -f|--file /PATH/TO/FILE -h|--help"

            exit 0;;

         *)

            echo "Usage is :`basename $0` -v|--version VERSION -a|--author AUTHOR -t|--time DATETIME -d|--description DESCRIPTION -f|--file /PATH/TO/FILE -h|--help"

            exit 2;;

       esac

      else

        break

      fi

    done

    #初始化配置

    if [ $FIL == 1 ];then

        if [ "`head -1 $FILE`" == "#!/bin/bash" ];then

          vim $FILE

          exit 0

        else

          echo "This is not a script."

          exit 3

        fi

    else

       echo "#!/bin/bash" >> $FILE

    fi

    if [ $AUT == 1 ];then

        echo "#Auther:$AUTH" >> $FILE

    fi

    if [ $DAT == 1 ];then

        echo "#Date:$DATE" >> $FILE

    fi

    if [ $DES == 1 ];then

        echo "#Description:$DESC" >> $FILE

    fi

    if [ $VER == 1 ];then

        echo "#Version:$VERS" >> $FILE

    fi

Comments Closed.